• Spring三 Bean的三种创建方式


    创建Bean的三种方式
    在大多数情况下,Spring容器直接通过new关键字调用构造器来创建Bean实例,而class属性指定Bean实例的实现类,但这不是实例化Bean的唯一方法。实际上,Spring支持使用以下三种方式来创建Bean:
    (1)调用构造器创建Bean
    (2)调用静态工厂方法创建Bean
    (3)调用实例工厂方法创建Bean
    一 构造器创建Bean实例
    如果不采用构造注入,Spring底层会调用Bean类的无参数构造器来创建实例,因此该类必须要提供无参数的构造器,并且class属性的值就是该Bean实例的实现类。Spring对Bean实例的所有属性执行默认初始化,即所有基本类型的值初始化为0或false,所有引用类型的值初始化为null。BeanFactory会根据配置文件决定依赖关系,先实例化所依赖的Bean实例,然后为Bean注入依赖关系,最后将一个完整的Bean实例返回给程序。
    如果采用构造注入,则使用<constructor-arg>配置一个构造器参数,Spring容器将使用带对应参数的构造器来创建Bean实例,Spring调用构造器传入的参数即可用于初始化Bean的实例变量,最后也将一个完整的Bean实例返回给程序。
    二 使用静态工厂方法创建Bean
    采用静态工厂方法创建Bean实例时,<bean>元素需要指定两个属性:
    class:值为静态工厂类的类名
    factory-method:指定静态工厂方法来生产Bean实例
    如果静态工厂方法需要参数,则使用<constructor-arg>元素传入。
    Being.java
    public interface Being {
    public void testBeing();
    }
    Dog.java
    public class Dog implements Being {
    public void setMsg(String msg) {
    this.msg = msg;
    }
    private String msg;
    @Override
    public void testBeing() {
    System.out.println(msg+",狗爱啃骨头");
    }
    }
    Cat.java
    public class Cat implements Being {
    public void setMsg(String msg) {
    this.msg = msg;
    }
    private String msg;
    @Override
    public void testBeing() {
    System.out.println(msg+",猫喜欢吃老鼠");
    }
    }
    BeingFactory.java
    BeingFactory工厂包含了一个getBeing()静态方法,该静态方法用于返回Being实例。
    public class BeingFactory {
    public static Being getBeing(String arg){
    if(arg.equalsIgnoreCase("dog")){
    return new Dog();
    }else{
    return new Cat();
    }
    }
    }
    BeingFactory类是一个静态工厂类,该类的getBeing()方法是一个静态工厂方法,该方法传入的参数决定返回Cat对象,还是Dog对象。
    public class BeingFactory {
    public static Being getBeing(String msg){
    if(msg.equalsIgnoreCase("dog")){
    return new Dog();
    }else{
    return new Cat();
    }
    }
    }
    ApplicationContext.xml
    //以下配置会驱动Spring调用BeingFactory的静态getBeing()方法来创建Bean,该Bean元素包含的constructor-arg元素用于为静态工厂方法指定参数
    <bean id="dog" class="SpringTest.BeingFactory" factory-method="getBeing">
    <constructor-arg value="dog" />
    //驱动Spring以"狗呢"为参数来执行dog的setMsg()方法
    <property name="msg" value="狗呢" />
    </bean>

    <bean id="cat" class="SpringTest.BeingFactory" factory-method="getBeing">
    <constructor-arg value="cat" />
    <property name="msg" value="猫呢" />
    </bean>
    测试:
    public class MainTest {
    public static void main(String[] args) {
    ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("SpringTest/ApplicationContext.xml");
    Being b1=ctx.getBean("dog",Being.class);
    b1.testBeing();
    Being b2=ctx.getBean("cat",Being.class);
    b2.testBeing();
    ctx.close();
    }
    }
    结果:狗呢,狗爱啃骨头
    猫呢,猫喜欢吃老鼠
    一旦为<bean>元素指定了factory-method属性,Spring就不再调用构造器来创建Bean实例,而是调用工厂方法来创建Bean实例。如果同时指定了class和factory-method两个属性,Spring就会调用静态工厂方法来创建Bean。
    Spring将先解析配置文件,并根据配置文件指定的信息,通过反射调用静态工厂类的静态工厂方法,将该静态工厂方法的返回值作为Bean实例。在这个过程中,Spring不再负责创建Bean实例,Bean实例是由用户提供的静态工厂类负责创建的。
    三 调用实例工厂方法创建Bean
    实例工厂方法与静态工厂方法只有一点不同:调用静态工厂方法只需要使用工厂类即可,而调用实例工厂方法则需要工厂实例。所以在配置时,静态工厂方法使用class指定静态工厂类,实例工厂方法使用factory-bean指定工厂实例。
    采用实例工厂方法创建Bean的<bean>元素时需要指定两个属性:
    factory-bean:工厂bean的id
    factory-method:实例工厂的工厂方法
    修改BeanFactory.java和AppliactionContext.xml
    BeanFactory.java
    public class BeingFactory {
    public Being getBeing(String msg){
    if(msg.equalsIgnoreCase("dog")){
    return new Dog();
    }else{
    return new Cat();
    }
    }
    }
    ApplicationContext.xml
    <bean id="beingFactory" class="SpringTest.BeingFactory" />
    <bean id="dog" factory-bean="beingFactory" factory-method="getBeing">
    <constructor-arg value="dog" />
    </bean>

    <bean id="cat" factory-bean="beingFactory" factory-method="getBeing">
    <constructor-arg value="cat" />
    </bean>

  • 相关阅读:
    Serializable读写类操作
    socket模拟通信
    使用poi实现生成excel文件
    注解形式的通知
    使用linkedhashmap实现LRU(最近最少使用缓存算法)
    websocket的使用
    centos systemctl daemon-reload 提示 no such file or directory 的一个原因
    mac 10.13 build 一个 redis desktop manager
    mac 必备工具
    supervisor 添加新配置不生效的问题
  • 原文地址:https://www.cnblogs.com/lyy-2016/p/5858279.html
Copyright © 2020-2023  润新知