在Spring BeanFactory容器中管理两种bean

在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;   
    }  
}  
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; }}
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();   
}  
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);   
    }  
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 {  

        // bean name处理  如果是以"&"开头  截取掉      

        final String beanName = transformedBeanName(name);   

        Object bean = null;   

        //单例的bean 只实例化一次  第一次实例化后会放到一个Map中 即singletonObjects map集合中  下次使用的时候直接拿    
        Object sharedInstance = getSingleton(beanName);  

        if (sharedInstance != null && args == null) {   

            // FactoryBean 相关处理 在此方法发生    

            //name 调用getBean时传入的参数     

            //beanName 截取"&"后的name    

            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);   
        }  
  

        else {   
            ...略  
        }  

        return bean;   
}  
protected Object doGetBean(final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { // bean name处理 如果是以"&"开头 截取掉 final String beanName = transformedBeanName(name); Object bean = null; //单例的bean 只实例化一次 第一次实例化后会放到一个Map中 即singletonObjects map集合中 下次使用的时候直接拿 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { // FactoryBean 相关处理 在此方法发生 //name 调用getBean时传入的参数 //beanName 截取"&"后的name bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { ...略 } return bean;}
protected Object getObjectForBeanInstance(  
        Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {  

    // 如果不是FactoryBean的相关调用 结束处理    

    //isFactoryDereference 方法判断name 是不是以"&"开始  如果以"&"开始 返回true    

    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;   

    //bean的定义为null    

    if (mbd == null) {   

        //缓存集合factoryBeanObjectCache中包含  当前bean getObject方法返回的实例  不需要在调用 直接返回    
        object = getCachedObjectForFactoryBean(beanName);  
    }  

    if (object == null) {   
        FactoryBean factory = (FactoryBean) beanInstance;  

        //containsBeanDefinition方法->  bean的定义map beanDefinitionMap集合中 是否包含该bean的定义    

        if (mbd == null && containsBeanDefinition(beanName)) {   
            mbd = getMergedLocalBeanDefinition(beanName);  
        }  

        boolean synthetic = (mbd != null && mbd.isSynthetic());   

        // FactoryBean getObject触发   并缓存到factoryBeanObjectCache集合中    
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);  
    }  

    return object;   
}  
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, RootBeanDefinition mbd) { // 如果不是FactoryBean的相关调用 结束处理 //isFactoryDereference 方法判断name 是不是以"&"开始 如果以"&"开始 返回true 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; //bean的定义为null if (mbd == null) { //缓存集合factoryBeanObjectCache中包含 当前bean getObject方法返回的实例 不需要在调用 直接返回 object = getCachedObjectForFactoryBean(beanName); } if (object == null) { FactoryBean factory = (FactoryBean) beanInstance; //containsBeanDefinition方法-> bean的定义map beanDefinitionMap集合中 是否包含该bean的定义 if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); // FactoryBean getObject触发 并缓存到factoryBeanObjectCache集合中 object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) {  

    //当前的factoryBean是否单例  并且  缓存singletonObjects‘Map中包含FactoryBean的自身实例    

    if (factory.isSingleton() && containsSingleton(beanName)) {   

        synchronized (getSingletonMutex()) {   

            // factoryBeanObjectCache 缓存的是 getObject返回的对象    

            Object object = this.factoryBeanObjectCache.get(beanName);   

            if (object == null) {   

                //getObject方法调用    
                object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);  

                //缓存 getObject方法返回的实例对象    

                this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));   
            }  

            return (object != NULL_OBJECT ? object : null);   
        }  
    }  

    else {   

        //getObject方法调用    

        return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);   
    }  
}  
protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) { //当前的factoryBean是否单例 并且 缓存singletonObjects‘Map中包含FactoryBean的自身实例 if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { // factoryBeanObjectCache 缓存的是 getObject返回的对象 Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { //getObject方法调用 object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess); //缓存 getObject方法返回的实例对象 this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT)); } return (object != NULL_OBJECT ? object : null); } } else { //getObject方法调用 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 {   

                // getObject方法调用    
                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);  
}  
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 { // getObject方法调用 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的生产 修饰做了很好的封装。

相关推荐