Spring使用静态工厂方法创建Bean

1. 使用静态工厂方法创建Bean

    使用静态工厂方法创建Bean实例时,class属性也必须指定,但此时class属性并不是指定Bean实例的实现类,而是静态工厂类。因为Spring需要知道是用哪个工厂来创建Bean实例。另外,还需要使用factory-method来指定静态工厂方法名,Spring将调用静态工厂方法(可能包含一组参数),来返回一个Bean实例,一旦获得了指定Bean实例,Spring后面的处理步骤与采用普通方法创建Bean实例则完全一样。需要注意的是,当使用静态工厂方法来创建Bean时,这个factory-method必须要是静态的。这段阐述听上去有点晕,话不多说,上代码:

先定义一个接口,静态方法产生的将是该接口的实例:

1public interface Animal { 2    public void sayHello(); 3}

下面是接口的两个实现类:

1public class Cat implements Animal { 2    private String msg; 3    //依赖注入时必须的setter方法 4    public void setMsg(String msg){ 5        this.msg = msg; 6    } 7    @Override 8    public void sayHello(){ 9        System.out.println(msg + ",喵~喵~"); 10    } 11} 12 13public class Dog implements Animal { 14    private String msg; 15    //依赖注入时必须的setter方法 16    public void setMsg(String msg){ 17        this.msg = msg; 18    } 19    @Override 20    public void sayHello(){ 21        System.out.println(msg + ",旺~旺~"); 22    } 23}

    下面的AnimalFactory工厂中包含了一个getAnimal的静态方法,该方法将根据传入的参数决定创建哪个对象。这是典型的静态工厂设计模式。

1public clas AnimalFactory { 2    public static Animal getAnimal(String type){ 3        if ("cat".equalsIgnoreCase(type)){ 4            return new Cat(); 5        } else { 6            return new Dog(); 7        } 8    } 9}

    如果需要指定Spring使用AnimalFactory来产生Animal对象,则可在Spring配置文件中作如下配置:

1<!-- 配置AnimalFactory的getAnimal方法,使之产生Cat --> 2<bean id="cat" class="com.abc.AnimalFactory" factory-method="getAnimal"> 3    <!-- 配置静态工厂方法的参数,getAnimal方法将产生Cat类型的对象 --> 4    <constructor-arg value="cat" /> 5    <!-- 通过setter注入的普通属性 --> 6    <property name="msg" value="猫猫" /> 7</bean> 8<!-- 配置AnimalFactory的getAnimal方法,使之产生Dog --> 9<bean id="dog" class="com.abc.AnimalFactory" factory-method="getAnimal"> 10    <!-- 配置静态工厂方法的参数,getAnimal方法将产生Dog类型的对象 --> 11    <constructor-arg value="dog" /> 12    <!-- 通过setter注入的普通属性 --> 13    <property name="msg" value="狗狗" /> 14</bean>

    从上面的配置可以看出:cat和dog两个Bean配置的class和factory-method完全相同,这是因为两个实例都使用同一个静态工厂类、同一个静态工厂方法产生得到的。只是为这个静态工厂方法指定的参数不同,使用<constructor-arg />元素来为静态工厂方法指定参数。

    主程序获取cat和dog两个Bean实例的方法不变,同样只需要调用Spring容器的getBean()即可:

1public class Test { 2    public static void main(String args[]){ 3        ApplicationContext context =  4                new ClassPathXmlApplicationContext("applicationContext.xml"); 5        Animal a1 = context.getBean("cat", Animal.class); 6        a1.sayHello(); 7        Animal a2 = context.getBean("dog", Animal.class); 8        a2.sayHello(); 9    } 10}

    输出结果:

1猫猫,喵~~ 2狗狗,旺~~

    使用静态工厂方法创建实例时必须提供工厂类和产生实例的静态工厂方法。通过静态工厂方法创建实例时需要对Spring配置文件做如下改变;

  • class属性不在是Bean实例的实现类,而是生成Bean实例的静态工厂类

  • 使用factory-method指定生产Bean实例的静态工厂方法

  • 如果静态工厂方法需要参数,使用<constructor-arg />元素为其配置

    当我们指定Spring使用静态工厂方法来创建Bean实例时,Spring将先解析配置文件,并根据配置文件指定的信息,通过反射调用静态工厂类的静态工厂方法,并将该静态工厂方法的返回值作为Bean实例,在这个过程中,Spring不再负责创建Bean实例,Bean实例是由用户提供的静态工厂方法提供的。

2. 使用实例工厂方法创建Bean

    实例工厂方法与静态工厂方法只有一点不同:调用静态工厂方法只需要使用工厂类即可,调用实例工厂方法则必须使用工厂实例。所以在Spring配置上也只有一点区别:配置静态工厂方法指定静态工厂类,配置实例工厂方法则指定工厂实例。同样是上面的例子将AnimalFactory修改为:

1public clas AnimalFactory { 2    public Animal getAnimal(String type){  //这里仅仅是去掉了static关键字 3        if ("cat".equalsIgnoreCase(type)){ 4            return new Cat(); 5        } else { 6            return new Dog(); 7        } 8    } 9}

    Spring文件修改为:

1<!-- 先配置工厂类 --> 2<bean id="animalFactory" class="com.abc.AnimalFactory" /> 3<!-- 这里使用factory-bean指定实例工厂类对象 --> 4<bean id="cat" factory-bean="animalFactory" factory-method="getAnimal"> 5    <!-- 同样指定factory-method的参数 --> 6    <constructor-arg value="cat" /> 7    <property name="msg" value="猫猫" /> 8</bean> 9 10<bean id="dog" factory-bean="animalFactory" factory-method="getAnimal"> 11    <constructor-arg value="dog" /> 12    <property name="msg" value="狗狗" /> 13</bean>

    测试类不用修改,输出结果和上面相同。

点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

SpringIOC官方文档解读

IoC容器本章介绍了Spring的控制反转(IoC)容器。1.1。SpringIoC容器和Bean简介本章介绍了反转控制(IoC)原则的Spring框架实现。IoC也称为依赖注入(DI)。在此过程中,对象可以通过①构造函数参数(),②工厂方法的参数③或在构造或从工厂方法返回后在对象实例上设置的属性来定义其依

Spring 学习笔记(三):Spring Bean

1Bean配置Spring可以看做是一个管理Bean的工厂,开发者需要将Bean配置在XML或者Properties配置文件中。实际开发中常使用XML的格式,其中<bean中的属性或子元素如下:id:Bean在BeanFactory中的唯一标识,在代码中通过BeanFac

Java设计模式之三种工厂模式

工厂模式实现了创建者和调用者的分离,实现了更好的解耦。详细分类:1)简单工厂模式(静态工厂模式);2)工厂方法模式;3)抽象工厂模式面向对象设计的基本原则:1)      OCP(开闭原则,OpenClosedPrinciple):一个软件的实体应当对扩展开放,对修改关闭。2)      

SpringAOP源码跟踪及学习

Spring版本4.3.2在拿到Bean实例以后,会经历一系列的初始化工作,如:工厂回调、init方法、后处理器在Bean初始化前后的处理等,在一般情况下(非factorymethod创建的Bean等),AOP代理对象的创建就在后处理器的处理方法中实现。入口以AbstractAutowireCapableB

IOC的使用

1.概要:在spring中,都是使用反射机制创建对象,将创建对象的权利交给spring容器,就是控制反转(ioc)对象创建方式有参构造无参构造工厂模式(静态,非静态)2.创建IDEA控制台测试项目!(https://oscimg.oschina.net/oscnet/a77ea6a2907139751d63