当我们需要用到工厂模式的时候,也可以交给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。