当我们需要用到工厂模式的时候,也可以交给Spring容器管理,此时Spring容器管理的就不是普通Bean,可称为“工厂Bean”。此时,应用程序调用getBean()是,Spring返回的不是直接创建的Bean,而是“工厂Bean”创建的Bean。如下图所示:
那Spring怎么配置工厂Bean,方法如下:
一,使用静态工厂
public class StaticFactoryBean
{
public static Object createEmptyObject()
{
return new Object();
}
}
XML配置,通过factory-method指定静态方法
<bean id="emptyObject" class="StaticFactoryBean" factory-method="createEmptyObject"></bean>
调用getBean("emptyObject")便会调用StaticFactoryBean的createEmptyObject()方法,返回一个Object对象
二,使用实例工厂
public class InstanceFactoryBean
{
private String format = "yy-MM-dd HH:mm:ss";
public void setFormat(String format)
{
this.format = format;
}
public String createTime()
{
return new SimpleDateFormat(format).format(new Date());
}
}
这时XML配置需要配置两个Bean:
<bean id="instanceFactoryBean" class="InstanceFactoryBean"> <property name="format" value="yy-MM-dd HH:mm:ss"></property> </bean> <bean id="currentTime" factory-bean="instanceFactoryBean" factory-method="createTime"></bean>
第一个Bean指定实例工厂,第二个Bean指定实例工厂名称和方法名。调用getBean("currentTime")即会调用InstanceFactoryBean的createTime方法
三,实现FactoryBean接口
FactoryBean源代码如下:
/**
* Interface to be implemented by objects used within a {@link BeanFactory}
* which are themselves factories. If a bean implements this interface,
* it is used as a factory for an object to expose, not directly as a bean
* instance that will be exposed itself.
*
* <p><b>NB: A bean that implements this interface cannot be used as a
* normal bean.</b> A FactoryBean is defined in a bean style, but the
* object exposed for bean references ({@link #getObject()} is always
* the object that it creates.
*
* <p>FactoryBeans can support singletons and prototypes, and can
* either create objects lazily on demand or eagerly on startup.
* The {@link SmartFactoryBean} interface allows for exposing
* more fine-grained behavioral metadata.
*
* <p>This interface is heavily used within the framework itself, for
* example for the AOP {@link org.springframework.aop.framework.ProxyFactoryBean}
* or the {@link org.springframework.jndi.JndiObjectFactoryBean}.
* It can be used for application components as well; however,
* this is not common outside of infrastructure code.
*/
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
注释大致翻译如下:<!--?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /-->
实现FactoryBean接口的对象,本身就是工厂类。如果一个bean实现了这个接口,它是用来作为对象创建的工厂,而不是直接将本身作为一个bean实例。
注:实现该接口的bean不能被用来作为一个普通的bean。一个FactoryBean定义bean的风格,但返回bean引用的对象getObject(),始终是它创建的对象。
FactoryBean可以支持单例和原型,延迟或启动创建对象。SmartFactoryBean接口允许更细粒度的控制。
在框架中有很多实现了此接口,例如为AOP:org.springframework.aop.framework.ProxyFactoryBean或org.springframework.jndi.JndiObjectFactoryBean。