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