标签:style blog class java tar ext
在Spring BeanFactory容器中管理两种bean
1.标准Java Bean
2,另一种是工厂Bean, 即实现了FactoryBean接口的bean 它不是一个简单的Bean 而是一个生产或修饰对象生成的工厂Bean
在向Spring容器获得bean时 对于标准的java Bean 返回的是类自身的实例
而FactoryBean 其返回的对象不一定是自身类的一个实例,返回的是该工厂Bean的getObject方法所返回的对象
一个简单的例子
-
public class SayHelloFactoryBeanImpl implements FactoryBean {
-
-
-
-
-
public Object getObject() throws Exception {
-
return new ChinaSayHelloServiceImpl();
-
}
-
-
-
-
-
public Class getObjectType() {
-
return ChinaSayHelloServiceImpl.class;
-
}
-
-
-
-
-
public boolean isSingleton() {
-
return false;
-
}
-
}
-
配置文件
-
<bean id="sayHelloFactoryBean" class="com.xx.service.impl.SayHelloFactoryBeanImpl" />
-
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext-server.xml"}, true);
-
-
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);
-
-
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方法发生的
-
public Object getBean(String name, Class requiredType, Object[] args) throws BeansException {
-
return doGetBean(name, requiredType, args, false);
-
}
-
protected Object doGetBean(final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
-
-
final String beanName = transformedBeanName(name);
-
Object bean = null;
-
-
Object sharedInstance = getSingleton(beanName);
-
if (sharedInstance != null && args == null) {
-
-
-
-
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
-
}
-
-
else {
-
...略
-
}
-
return bean;
-
}
-
protected Object getObjectForBeanInstance(
-
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
-
-
-
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
-
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
-
}
-
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
-
return beanInstance;
-
}
-
Object object = null;
-
-
if (mbd == null) {
-
-
object = getCachedObjectForFactoryBean(beanName);
-
}
-
if (object == null) {
-
FactoryBean factory = (FactoryBean) beanInstance;
-
-
if (mbd == null && containsBeanDefinition(beanName)) {
-
mbd = getMergedLocalBeanDefinition(beanName);
-
}
-
boolean synthetic = (mbd != null && mbd.isSynthetic());
-
-
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
-
}
-
return object;
-
}
-
protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) {
-
-
if (factory.isSingleton() && containsSingleton(beanName)) {
-
synchronized (getSingletonMutex()) {
-
-
Object object = this.factoryBeanObjectCache.get(beanName);
-
if (object == null) {
-
-
object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
-
-
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
-
}
-
return (object != NULL_OBJECT ? object : null);
-
}
-
}
-
else {
-
-
return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
-
}
-
}
-
private Object doGetObjectFromFactoryBean(
-
final FactoryBean factory, final String beanName, final boolean shouldPostProcess)
-
throws BeanCreationException {
-
AccessControlContext acc = AccessController.getContext();
-
return AccessController.doPrivileged(new PrivilegedAction() {
-
public Object run() {
-
Object object;
-
-
try {
-
-
object = factory.getObject();
-
}
-
catch (FactoryBeanNotInitializedException ex) {
-
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
-
}
-
catch (Throwable ex) {
-
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
-
}
-
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
-
throw new BeanCurrentlyInCreationException(
-
beanName, "FactoryBean which is currently in creation returned null from getObject");
-
}
-
-
if (object != null && shouldPostProcess) {
-
try {
-
object = postProcessObjectFromFactoryBean(object, beanName);
-
}
-
catch (Throwable ex) {
-
throw new BeanCreationException(beanName, "Post-processing of the FactoryBean‘s object failed", ex);
-
}
-
}
-
-
return object;
-
}
-
}, acc);
-
}
当一个受Spring容器管理的bean 如果实现了FactoryBean接口 在bean实例化(getBean)阶段 Spring会调用该bean的getObejct方法 返回的不一定是自身的实例
Spring 框架中有很多FactoryBean 例如RmiProxyFactoryBean, SqlMapClientFactoryBean. LocalSessionFactoryBean等都是通过FactoryBean getObject方法驱动起来的.对bean的生产 修饰做了很好的封装。
原文地址:http://blog.csdn.net/java2000_wl/article/details/7410714
Spring FactoryBean源码浅析,布布扣,bubuko.com
Spring FactoryBean源码浅析
标签:style blog class java tar ext
原文地址:http://blog.csdn.net/aigoogle/article/details/25540017