7.7.2 使用静态工厂方法创建Bean
使用静态工厂方法创建Bean实例时, class属性也必须指定,但此时class属性并不是指定Bean实例的实现类,而是静态工厂类, Spring通过该属性知道由哪个工厂类来创建Bean实例。
除此之外,还需要使用factory-method属性来指定静态工厂方法, Spring将调用静态工厂方法(可能包含一组参数)返回一个Bean实例,一旦获得了指定Bean实例, Spring后面的处理步骤与采用普通方法创建Bean实例则完全一样。
下面的Bean要由factory-method指定的静态工厂方法来创建,所以这个<bean>元素的class属性指定的是静态工厂类, factory-method指定的工厂方法必须是静态的。
由此可见,采用静态工厂方法创建Bean实例时,<bean>元素需要指定如下两个属性:
| 属性 | 描述 | ||
|---|---|---|---|
class |
该属性的值设置为静态工厂类的类名. |
||
factory- method |
该属性指定静态工厂方法来生产Bean实例。 |
||
如果静态工厂方法需要参数,则使用<constructor-arg>元素传入。 |
|||
| # 程序示例 # | |||
| ## 项目结构 ## | |||
|
下面先定义一个Being接口,静态工厂方法所生产的产品是该接口的实例。下面是接口的两个实现类,静态工厂方法将会产生这两个实现类的实例。
Cat.java
1 | package org.crazyit.app.service.impl; |
Dog.java
1 | package org.crazyit.app.service.impl; |
BeingFactory.java
下面的BeingFactory工厂包含了一个getBeing()静态方法,该静态方法用于返回一个Being实例这就是典型的静态工厂类.
1 | package org.crazyit.app.factory; |
上面的BeingFactory类是一个静态工厂类,该类的getBeing()方法是一个静态工厂方法,该方法根据传入的参数决定返回Cat对象,还是Dog对象。
如果需要指定Spring让BeingFactory来生产Being对象,则应该按如下静态工厂方法的方式来配置Dog的Bean,Cat的Bean。本应用中的Spring配置文件如下。
beans.xml
1 |
|
从上面的配置文件可以看出,cat和dog两个Bean配置的cass属性和factory-method属性完全相同——这是因为这两个实例都是由同一个静态工厂类、同一个静态工厂方法生产得到的。配置这两个Bean实例时指定的静态工厂方法的参数值不同,配置工厂方法的参数值使用<contructor-arg>元素,如上配置文件所示。
一旦为<bean>元素指定了factory-method属性, Spring就不再调用构造器来创建Bean实例,而是调用工厂方法来创建Bean实例。如果同时指定了class和factory-method两个属性, Spring就会调用静态工厂方法来创建Bean。上面两段配置驱动Spring执行的Java代码已在注释中给出。
主程序获取Spring容器的cat、dog两个Bean实例的方法依然无须改变,只需要调用Spring容器的getBean()方法即可。主程序如下。
SpringTest.java
1 | package lee; |
使用静态工厂方法创建实例时必须提供工厂类,工厂类包含产生实例的静态工厂方法。
使用静态工厂方法创建实例时对配置文件的要求
通过静态厂方法创建实例时需要对配置文件进行如下改变:
class属性的值不再是Bean实例的实现类,而是生成Bean实例的静态工厂类- 使用
factory-method属性指定创建Bean实例的静态工厂方法 - 如果静态工厂方法需要参数,则使用
<constructor-arg>元素指定静态工厂方法的参数。
指定Spring使用静态工厂方法来创建Bean实例时, Spring将先解析配置文件,并根据配置文件指定的信息,通过反射调用静态工厂类的静态工厂方法,将该静态工厂方法的返回值作为Bean实例。在这个过程中, Spring不再负责创建Bean实例,Bean实例是由用户提供的静态工厂类负责创建的.
当静态工厂方法创建了Bean实例后, Spring依然可以管理该Bean实例的依赖关系,包括为其注入所需的依赖Bean、管理其生命周期等。
原文链接: 7.7.2 使用静态工厂方法创建Bean