spring中baen的生命週期,及生命週期中的作用
最近在看spring原始碼,所以總結下spring的生命週期和各個階段的作用。
spring的生命週期概括起來主要如下:
- 例項化
- 屬性注入 ioc注入
- 實現了BeanNameAware 則執行setBeanName方法
- 實現了BeanFactoryAware 則執行 setBeanFactory方法,p125
- 實現了ApplicationContextAware 執行setApplicationContest方法 ,感覺可以參照p125
- BeanPostProcessor 執行postProcessBeforeInitiliaztion
- 實現了InitiliazingBean 執行afterPropertiesSet方法
- 配置檔案定義了init-method 則執行對應初始化方法
- BeanPostProcessor 執行postProcessorfterInitilization
- Bean可以使用
- 關閉容器
- DisposableBean 執行destroy方法
- 配置檔案定義了destory-method 則執行destory-method
下面進行簡單的分析
1-2步進行例項化和各種屬性的填充,你所用的Autowire等註解也會在這個時候生效
3-5步是執行***Aware介面中的方法,本質上就是把spring中的元件(如applicationContext,beanFactory等)通過介面的方式傳給實體類,關於****Aware的介面的使用和作用以BeanFactoryAware為例:
@Component public class PostProcessor implements BeanFactoryAware { BeanFactory factory; @Override // beanFactory是spring提供給你的可用BeanFactory public void setBeanFactory(BeanFactory beanFactory) throws BeansException { factory = beanFactory; } public void meythod1(){ factory.getBean("beanName"); System.out.println("use Bean -----"); } }
你的類實現了BeanFactoryAware介面,就要實現setBeanFactory方法,該方法的本質就是在例項化bean的時候,會通過setBeanFactory將beanFactory提供給你,然後你就可以使用beanFactory了。
如果想了解beanFactory和ApplicationContext的區別和關係參考這裡。
6和9步是BeanPostProcessor的應用
先對BeanPostProcessor的使用做出如下說明:
- beanPostPocesser被實現並註解後,所有的bean在初始化時都會被執行所有beanPostPocessor實現類的postProcessBeforeInitialization和postProcessAfterInitialization方法,注意兩個所有
- 多個類實現了beanPostPocessor,如果存在返回為空,則會僅有一個類的postProcessBeforeInitialization方法執行了
- 如果僅需要對某特定類處理可以在postProcessBeforeInitialization和postProcessAfterInitialization方法內使用 instanceof 方法,做針對某特定類的處理
- 在實現的方法內修改返回的例項,即按照你的要求返回需要的代理類或者別的類,這個會在下面繼續說明用法
下面看下BeanPostProcessor的實際使用:
第一個BeanPostProcessor的實現類PostProcessor
@Component
public class PostProcessor implements BeanPostProcessor,BeanFactoryAware {
BeanFactory factory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
factory = beanFactory;
}
public void meythod1(){
factory.getBean("contextHolder");
System.out.println("postProcessor ---meythod1 -----");
}
@Override
// 這裡的o就是當前呼叫該方法的bean的實體類,s對應實體類的beanName
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
// 如果是PostProcessorInclude的實體類,則將實際實體類替換為PostProcessor的實體類
// 即ac.getBean("postProcessorInclude");實際會返回PostProcessor的實體類,不再是postProcessorInclude的實體類了
if(o instanceof PostProcessorInclude){
System.out.println("PostProcessor-BeforeInitialization----"+s);
return factory.getBean("postProcessor");
}
return o;
}
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessor---AfterInitialization----"+s);
return o;
}
}
第二個BeanPostprocessor的實現類PostProcessorImpl
@Component
public class PostProcessorImpl implements BeanPostProcessor {
public void meythod1(){
System.out.println("PostProcessorNew ===do -----");
}
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("PostProcessorImpl---before----"+s);
return o;
}
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("PostProcessorImpl---after----"+s);
return o;
}
}
第三個類,實現了InitializingBean介面
@Component
public class PostProcessorInclude implements InitializingBean {
public void meythod1(){
System.out.println("PostProcessorInclude---meythod1---do -----");
}
@Override
//此場景下,該方法不會執行,受PostProcessor的postProcessBeforeInitialization方法影響
public void afterPropertiesSet() throws Exception {
System.out.println("PostProcessorInclude---afterPropertiesSet");
}
}
執行程式碼:
// 上下文只需要下面一行程式碼就會自動呼叫BeanPostProcessor的方法
ApplicationContext ac=new ClassPathXmlApplicationContext( new String[]{"applicationContext.xml"});
Object postProcessor = ac.getBean("postProcessorInclude");
if(postProcessor instanceof PostProcessor){
postProcessor = (PostProcessor)postProcessor;
((PostProcessor) postProcessor).meythod1();
System.out.println("說明返回代理----生效");
}else if(postProcessor instanceof CheckUtils){
postProcessor = (CheckUtils)postProcessor;
((CheckUtils) postProcessor).readProperty();
}else if(postProcessor instanceof PostProcessorInclude){
System.out.println("PostProcessorImpl");
System.out.println("說明返回代理沒有生效");
}else if(postProcessor instanceof PostProcessorInclude){
((PostProcessorInclude) postProcessor).meythod1();
}
結果如下:
PostProcessorImpl---before----contextHolder
postProcessor---AfterInitialization----contextHolder
PostProcessorImpl---after----contextHolder
PostProcessor-BeforeInitialization----postProcessorInclude
PostProcessorImpl---before----postProcessorInclude
postProcessor---AfterInitialization----postProcessorInclude
PostProcessorImpl---after----postProcessorInclude
PostProcessorImpl---before----org.springframework.context.event.internalEventListenerProcessor
postProcessor---AfterInitialization----org.springframework.context.event.internalEventListenerProcessor
PostProcessorImpl---after----org.springframework.context.event.internalEventListenerProcessor
PostProcessorImpl---before----org.springframework.context.event.internalEventListenerFactory
postProcessor---AfterInitialization----org.springframework.context.event.internalEventListenerFactory
PostProcessorImpl---after----org.springframework.context.event.internalEventListenerFactory
postProcessor ---meythod1 -----
說明返回代理----生效
原始碼中對postProcessBeforeInstantiation的解釋是 給beanpostprocessor一個返回代理而不是目標bean例項的機會。
實際我在例項1中 return factory.getBean("postProcessor");這段程式碼生效了,ac.getBean("postProcessorInclude"),不再是返回PostProcessorImpl的實體類,而是postProcessor的實體類。
原始碼如下:
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
第7步:實現了InitiliazingBean 則執行afterPropertiesSet方法,需要說明的是:
上面的程式碼第三個類PostProcessorInclude的afterPropertiesSet方法就不會執行。因為在postProcessBeforeInitialization方法中做了替換,不再繼續向下執行,如果將return factory.getBean("postProcessor");註釋掉,你會發現afterPropertiesSet方法會正常執行。
至於別的7 8 10 11 12 13就不再解釋了,比較簡單。