Spring框架

2018-09-14  本文已影响0人  bbbbb4444

一、概念

1.依赖注入

依赖注入DI(Dependency injection):接管对象的创建工作,并将该对象的引用注入需要该对象的组件。

A用到了B中的一些方法,若B是一个接口,有好多接口B的实现类,A的可重用性大大降低,使用new的话无法使用B的其他实现。为了能依赖注入,需要编写特定的set方法或者构建方法。

1.0版本:Spring同时支持sertter和构造器方式的依赖注入。
2.5版本:Spring可通过Autowired注解,支持基于field方式的依赖注入,但是缺点是程序必须引org.springframework.beans.factory.annotation.Autowired。

2.控制反转IOC

控制反转IOC(Inversion of Control)是一种设计思想,用来降低耦合度。是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方。


使用IOC前 使用IOC后

3.Spring的配置

使用Spring,程序几乎将所有重要的对象创建工作将交给Spring,配置如何注入依赖。Spring支持XML或注解两种方式。
需要创建一个ApplicationContext对象,代表一个Spring控制反转容器,org.springframework.context.ApplicationContext接口有多个实现,包括ClassPathXMLApplicationContext和FileSystemXmlApplicationContext和WebXmlApplicationContext,两个实现都需要至少一个包含beans信息的XML文件。两个都是用来加载XML配置文件,一个是类加载,一个是文件加载。

二、IOC的使用

1.通过构造器创建bean实例

构造器创建bean实例文件
(1)创建配置文件config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">

        <!--构造器创建bean实例-->
        <bean name="product" class="Product">
            <property name="description" value="测试的东西"></property>
        </bean>
</beans>

(2)创建实体类Product.java
public class Product {
    private String name;
    private String description;
    private float price;

    public Product() {
        System.out.println("==============Product()==============");
    }

    public Product(String name, String description, float price) {
        this.name = name;
        this.description = description;
        this.price = price;
    }
    public String getName() {
        System.out.println("!!!!!!get name()!!!!!!");
        return name;
    }
    public void setName(String name) {
        System.out.println("!!!!!!set name()!!!!!!");
        this.name = name;
    }
    public String getDescription() {
        System.out.println("!!!!!!getDescription()!!!!!!");
        return description;
    }
    public void setDescription(String description) {
        System.out.println("!!!!!!setDescription()!!!!!!");
        this.description = description;
    }
    public float getPrice() {
        System.out.println("!!!!!!getPrice()!!!!!!");
        return price;
    }
    public void setPrice(float price) {
        System.out.println("!!!!!!setPrice()!!!!!!");
        this.price = price;
    }
}
(3)创建运行类Run.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Run{
    public static void main(String[] args){
        ApplicationContext context = new FileSystemXmlApplicationContext
                ("config.xml");
        Product product1 = context.getBean("product", Product.class);
        product1.setName("set的name");
        System.out.println("得到: " + product1.getName()+"\t"+product1.getDescription());
    }
}
(4)通过一个run.bat编译运行。
@echo off
set jarPath= %cd%\lib\commons-logging-1.1.jar;%cd%\lib\org.springframework.asm-3.0.1.RELEASE-A.jar;%cd%\lib\org.springframework.beans-3.0.1.RELEASE-A.jar;%cd%\lib\org.springframework.context-3.0.1.RELEASE-A.jar;%cd%\lib\org.springframework.core-3.0.1.RELEASE-A.jar;%cd%\lib\org.springframework.expression-3.0.1.RELEASE-A.jar;
javac  -encoding UTF-8 -cp %jarPath% Run.java
javac Product.java
java -cp %jarPath% Run
pause
运行结果

2.通过静态工厂方法创建bean实例

静态工厂方法创建Bean实例,静态工厂是一个Java类,那么该class属性指定的就是该工厂的实现类,而不再是Bean的实现类,告诉Spring这个Bean应该由哪个静态工厂创建,另外我们还需要添加factory-method属性来指定由工厂的哪个方法来创建Bean实例,因此使用静态工厂方法创建Bean实例需要为<bean/>元素指定如下属性:

静态工厂方法文件

与上面构造器创造创建bean有些许差别

(1)config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">

        <!--工厂方法创建bean实例-->
        <bean id="product2" class="ProductFactory"
            factory-method="setProduct">
            <!-- 为静态工厂的setProduct()方法传参 -->
            <constructor-arg value="传参么么哒"/>
            <!-- 调用setDescription()方法为msg属性注入参数值 -->
            <property name="description" value="注入的description"/>
        </bean> 
</beans>
(2)ProductFactory.java
public class ProductFactory {
    public static Product setProduct(String arg){
        Product ptest = new Product(arg);
        return ptest;
    }
}
(3)Run.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Run{
    public static void main(String[] args){
        ApplicationContext context = new FileSystemXmlApplicationContext
                ("config.xml");
        Product product1 = context.getBean("product2", Product.class);
        System.out.println("得到description: " + product1.getDescription()+"    "+"得到name"+product1.getName());
    }
}

其他的Product.java和run.bat参考1中做法,运行结果为:


静态工厂方法运行结果

3.通过实例工厂方法创建bean实例

静态工厂通过class指定静态工厂实现类然后通过相应的方法创建即可,调用实例工厂则需要先创建该工厂的Bean实例,然后引用该实例工厂Bean的id创建其他Bean,在实例工厂中通过factory-bean指定工厂Bean的实例,在调用实例化工厂方法中,不用在<bean/>中指定class属性,因为这时,不用直接实例化该Bean,而是通过调用实例化工厂的方法,创建Bean实例,调用实例化工厂需要为<bean/>指定一下两个属性

实例工厂方法文件

在2的基础上修改了config.xml和ProductFactory.java

(1)config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">

        <bean name="MyProductFactory" class="ProductFactory"/>
        <!-- 由实例工厂Bean的setProduct()方法,创建Bean, -->
        <bean id="product3" factory-bean="MyProductFactory" factory-method="setProduct">
            <!-- 为该方法传入参数-->
            <constructor-arg value="传参33"/>
            <property name="description" value="注入的name33"/>
        </bean>
        <bean id="product4" factory-bean="MyProductFactory" factory-method="setProduct">
            <!-- 为该方法传入参数-->
            <constructor-arg value="传参44"/>
            <property name="description" value="注入的name44"/>
        </bean>
</beans>
(2)ProductFactory.java
public class ProductFactory {
    public Product setProduct(String arg){
        Product ptest = new Product(arg);
        return ptest;
    }
}
(3)Run.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Run{
    public static void main(String[] args){
        ApplicationContext context = new FileSystemXmlApplicationContext
                ("config.xml");
        Product product3 = context.getBean("product3", Product.class);
        System.out.println("得到product3"+product3.getName()+product3.getDescription());

        Product product4 = context.getBean("product4", Product.class);
        System.out.println("得到product4"+product4.getName()+product4.getDescription());
    }
}
其他的Product.java和run.bat参考1中做法,运行结果为: 实例工厂方法运行结果

4.注意

(1)在配置spring标签是name和id的区别

id和name都是spring 容器中中bean 的唯一标识符。 同一个配置文件id和name不能重复。

(2)调用实例工厂创建Bean和调用静态工厂的区别。

其实调用实例工厂创建Bean和调用静态工厂创建Bean的区别就在于,调用实例工厂将工厂单独拿了出来(先实例化工厂)创建一个工厂Bean,通过工厂<bean>的class属性指定工厂的实现类,然后再需要创建其他Bean时,只需要在该<bean/>元素添加factory-bean、factory-method指定该Bean是有哪个实例工厂的哪个方法创建就可以了,放在现实生活中就是:我们先找一个地方创建一个工厂,id指定工厂注册名字(xxx有限公司),class指定公司所在地,工厂里面有车间(创造其他Bean的方法),那好有了工厂我们再需要创建其他Bean时,只需要指定这个Bean是由,哪个工厂的哪个车间创建的即可,也就是只需要在该<bean/>元素添加factory-bean、factory-method属性即可

上一篇 下一篇

猜你喜欢

热点阅读