欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

new ObjectFactory() { public Object getObjec CAD加密 t() thro

点击: 次  来源:宝鼎软件 时间:2017-06-01

原文出处: 五月的仓颉

代码进口

上文【Spring源码阐明】Bean加载流程概览,较量具体地阐明白Spring上下文加载的代码进口,而且在AbstractApplicationContext的refresh要领中,点出了finishBeanFactoryInitialization要领完成了对付所有非懒加载的Bean的初始化。

finishBeanFactoryInitialization要领中挪用了DefaultListableBeanFactory的preInstantiateSingletons要领,本文针对preInstantiateSingletons举办阐明,解读一下Spring是如何初始化Bean实例工具出来的。

DefaultListableBeanFactory的preInstantiateSingletons要领

DefaultListableBeanFactory的preInstantiateSingletons要领,顾名思义,初始化所有的单例Bean,软件开发,看一下要领的界说:

public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isInfoEnabled()) {
        this.logger.info("Pre-instantiating singletons in " + this);
    }
    synchronized (this.beanDefinitionMap) {
        // Iterate over a copy to allow for init methods which in turn register new bean definitions.
        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                            public Boolean run() {
                                return ((SmartFactoryBean) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }
    }
}

前面的代码较量简朴,按照beanName拿到BeanDefinition(即Bean的界说)。由于此要领实例化的是所有非懒加载的单例Bean,因此要实例化Bean,劳务派遣管理系统,必需满意11行的三个界说:

(1)不是抽象的

(2)必需是单例的

(3)必需长短懒加载的

接着简朴看一下第12行~第29行的代码,这段代码主要做的是一件工作:首先判定一下Bean是否FactoryBean的实现,接着判定Bean是否SmartFactoryBean的实现,如果Bean是SmartFactoryBean的实现而且eagerInit(这个单词字面意思是盼愿加载,找不到一个好的词语去翻译,意思就是界说了这个Bean需要当即加载的意思)的话,会当即实例化这个Bean。Java开拓人员不需要存眷这段代码,因为SmartFactoryBean根基不会用到,我翻译一下Spring官网对付SmartFactoryBean的界说描写:

  • FactoryBean接口的扩展接口。接话柄现并不暗示是否老是返回单独的实例工具,好比FactoryBean.isSingleton()实现返回false的环境并不清晰地暗示每次返回的都是单独的实例工具
  • 不实现这个扩展接口的简朴FactoryBean的实现,FactoryBean.isSingleton()实现返回false老是简朴地汇报我们每次返回的都是单独的实例工具,袒暴露来的工具只可以或许通过呼吁会见
  • 留意:这个接口是一个有非凡用途的接口,主要用于框架内部利用与Spring相关。凡是,应用提供的FactoryBean接话柄现该当只需要实现简朴的FactoryBean接口即可,新要领该当插手到扩展接口中去
  • 代码示例

    为了后头的代码阐明利便,事先我界说一个Bean:

    package org.xrq.action;
    
    import org.springframework.beans.factory.BeanClassLoaderAware;
    import org.springframework.beans.factory.BeanNameAware;
    import org.springframework.beans.factory.InitializingBean;
    
    public class MultiFunctionBean implements InitializingBean, BeanNameAware, BeanClassLoaderAware {
    
        private int    propertyA;
    
        private int    propertyB;
    
        public int getPropertyA() {
            return propertyA;
        }
    
        public void setPropertyA(int propertyA) {
            this.propertyA = propertyA;
        }
    
        public int getPropertyB() {
            return propertyB;
        }
    
        public void setPropertyB(int propertyB) {
            this.propertyB = propertyB;
        }
    
        public void initMethod() {
            System.out.println("Enter MultiFunctionBean.initMethod()");
        }
    
        @Override
        public void setBeanClassLoader(ClassLoader classLoader) {
            System.out.println("Enter MultiFunctionBean.setBeanClassLoader(ClassLoader classLoader)");
        }
    
        @Override
        public void setBeanName(String name) {
            System.out.println("Enter MultiFunctionBean.setBeanName(String name)");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("Enter MultiFunctionBean.afterPropertiesSet()");
        }
    
        @Override
        public String toString() {
            return "MultiFunctionBean [propertyA=" + propertyA + ", propertyB=" + propertyB + "]";
        }
    
    }