在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方法的時候,就直接把這個代理對象返回出去了。