Spring FactoryBean源码浅析
在Spring BeanFactory容器中管理两种bean
1.标准Java Bean
2,另一种是工厂Bean, 即实现了FactoryBean接口的bean 它不是一个简单的Bean 而是一个生产或修饰对象生成的工厂Bean
在向Spring容器获得bean时 对于标准的java Bean 返回的是类自身的实例
而FactoryBean 其返回的对象不一定是自身类的一个实例,返回的是该工厂Bean的getObject方法所返回的对象
一个简单的例子
- public class SayHelloFactoryBeanImpl implements FactoryBean {
- /**
- * 返回该工厂生成的bean
- */
- public Object getObject() throws Exception {
- return new ChinaSayHelloServiceImpl();
- }
- /**
- * getObject返回对象对应的Class
- */
- public Class getObjectType() {
- return ChinaSayHelloServiceImpl.class;
- }
- /**
- * getObject返回的对象 是否是一个单例
- */
- public boolean isSingleton() {
- return false;
- }
- }
}
- 配置文件
- <bean id="sayHelloFactoryBean" class="com.xx.service.impl.SayHelloFactoryBeanImpl" />
配置文件 <bean id="sayHelloFactoryBean" class="com.xx.service.impl.SayHelloFactoryBeanImpl" />
- ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext-server.xml"}, true);
- //bean的 getObject方法 返回的对象
- Object object = context.getBean("sayHelloFactoryBean");
- System.out.println(object);
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext-server.xml"}, true); //bean的 getObject方法 返回的对象 Object object = context.getBean("sayHelloFactoryBean"); System.out.println(object);
控制台输出
com.xx.service.impl.ChinaSayHelloServiceImpl@1f66cff
容器返回的是 bean getObject方法返回对象 而不是SayHelloFactoryBeanImpl自身的实例 当然可以用“&”符号转义 获得FactoryBean的自身实例
- ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext-server.xml"}, true);
- //可以用转义符"&"来获得FactoryBean本身实例
- System.out.println(context.getBean("&sayHelloFactoryBean"));
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext-server.xml"}, true); //可以用转义符"&"来获得FactoryBean本身实例 System.out.println(context.getBean("&sayHelloFactoryBean"));
控制台输出
com.xx.service.impl.SayHelloFactoryBeanImpl@75e4fc
下面看看FactoryBean是怎么实现的
Spring FactoryBean接口定义
- public interface FactoryBean {
- Object getObject() throws Exception;
- Class getObjectType();
- boolean isSingleton();
- }
bean的实例化 是在AbstractBeanFactory getBean方法发生的
当一个受Spring容器管理的bean 如果实现了FactoryBean接口 在bean实例化(getBean)阶段 Spring会调用该bean的getObejct方法 返回的不一定是自身的实例
Spring 框架中有很多FactoryBean 例如RmiProxyFactoryBean, SqlMapClientFactoryBean. LocalSessionFactoryBean等都是通过FactoryBean getObject方法驱动起来的.对bean的生产 修饰做了很好的封装。