美文网首页
Spring框架

Spring框架

作者: bbbbb4444 | 来源:发表于2018-09-14 13:44 被阅读0次

    一、概念

    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配置文件,一个是类加载,一个是文件加载。

    • FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径。
    • ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件,myeclipse中直接放到src中即可。
    • WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。

    二、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/>元素指定如下属性:

    • class:指定静态工厂的实现类,告诉Spring该Bean实例应该由哪个静态工厂创建(指定工厂地址)
    • factory-method:指定由静态工厂的哪个方法创建该Bean实例(指定由工厂的哪个车间创建Bean)
      如果静态工厂方法需要参数,则使用<constructor-arg.../>元素传入
    静态工厂方法文件

    与上面构造器创造创建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/>指定一下两个属性

    • factory-bean :该属性指定工厂Bean的id
    • factory-method:该属性指定实例工厂的工厂方法。
    实例工厂方法文件

    在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不能重复。

    • id: 一个bean的唯一标识 , 命名格式必须符合XML ID属性的命名规范
    • name: 可以用特殊字符,并且一个bean可以用多个名称:name=“bean1,bean2,bean3” ,用逗号或者分号或者空格隔开。如果没有id,则name的第一个名称默认是id。
    (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属性即可

    相关文章

      网友评论

          本文标题:Spring框架

          本文链接:https://www.haomeiwen.com/subject/bhxogftx.html