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方法的时候,就直接把这个代理对象返回出去了。

你可能感兴趣的:(properties)