initMethod 和 afterPropertiesSet 以及 AwareMethod方法的執行時機


在spring開發中,我們定義bean
經常會需要用到beanFactory對象,這就需要實現BeanFactoryAware這種類型的接口,它有一個setBeanFactory方法
 
在xml中配置bean 的時候,我們也可以指定initMethod方法
 
在bean類定義的時候可以實現InitializingBean,提供一個afterPropertiesSet方法的實現
 
 
以上者3中情況我們經常用到,下面來分析一下spring是如何處理這3種情況的,他們的調用時機是怎么樣的?
 
 
在AbstractAutowireCapableBeanFactory類中
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        //...省略很多代碼 下面開始初始化 關鍵就是兩個步驟
        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);   //這里執行了注入屬性和依賴的操作
            if (exposedObject != null) {
                exposedObject = initializeBean(beanName, exposedObject, mbd);//這里執行了initMethod 和 afterPropertiesSet
            }
        }
         //...省略很多代碼 
        return exposedObject;
    }

 重點看initializeBean(beanName, exposedObject, mbd)

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    invokeAwareMethods(beanName, bean);

                    return null;
                }
            }, getAccessControlContext());
        }
        else {
            //這里判斷是BeanFactoryAware, ServletContextAware之類的aware類型,如果是的話就執行對於的Aware方法
            //把beanFactory啊 servletContext啊之類的依賴set進去
            invokeAwareMethods(beanName, bean);
        }
        
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {   
            //如果實現了BeanPostProcessor接口 這里會執行postProcessBeforeInitialization方法
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
        try {
            //這里就開始執行initMethod 和 afterPropertiesSet方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }

進入invokeInitMethods(beanName, wrappedBean, mbd);

    protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
            throws Throwable {
        boolean isInitializingBean = (bean instanceof InitializingBean);//先判斷是否實現了InitializingBean接口
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
             //.....省略很多代碼            
            else {
                //執行afterPropertiesSet()方法
                ((InitializingBean) bean).afterPropertiesSet(); 
            }
        }
        if (mbd != null) {
            String initMethodName = mbd.getInitMethodName();
            if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                //如果配置了initMethod 就執行initMethod方法 這里只是取到了方法名,顯然是要通過反射調用了
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }

 

 

 

經過這些源碼的分析 可以得出結論
首先這些過程都在很重要的抽象類AbstractAutowireCapableBeanFactory抽象類中 這個類就是常用的DefaultListableBeanFactory的父類
1.spring先根據beanDefinition創建出了bean 的實例
 
2.執行了populateBean方法 把屬性和依賴都注入了  
 
3.執行了 initializeBean(beanName, exposedObject, mbd);方法 這里面才進行了Aware相關方法,afterPropertiesSet 和 initMethod 方法的調用
可見這3種方法調用又都是在bean實例已經創建好,且屬性值和依賴的其他bean實例都已經注入以后 才得到調用的
 
4.后面的代碼可以看出 Aware相關方法最先執行,afterPropertiesSet 第二執行  ,initMethod 方法最后執行
 
另外多說一句 afterPropertiesSet方法是很有用的,比如 AOP事務管理用到的類,TransactionProxyFactoryBean 就是利用afterPropertiesSet方法事先把事務管理器
TransactionManager的代理類對象給生成好了,后面調用FactoryBean對象的getObject方法的時候,就直接把這個代理對象返回出去了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM