1. 程式人生 > >spring中baen的生命週期,及生命週期中的作用

spring中baen的生命週期,及生命週期中的作用

最近在看spring原始碼,所以總結下spring的生命週期和各個階段的作用。

spring的生命週期概括起來主要如下:

  1. 例項化
  2. 屬性注入 ioc注入
  3. 實現了BeanNameAware 則執行setBeanName方法 
  4. 實現了BeanFactoryAware 則執行 setBeanFactory方法,p125
  5. 實現了ApplicationContextAware 執行setApplicationContest方法 ,感覺可以參照p125
  6. BeanPostProcessor 執行postProcessBeforeInitiliaztion
  7. 實現了InitiliazingBean 執行afterPropertiesSet方法
  8. 配置檔案定義了init-method 則執行對應初始化方法
  9. BeanPostProcessor 執行postProcessorfterInitilization
  10. Bean可以使用
  11. 關閉容器
  12. DisposableBean 執行destroy方法
  13. 配置檔案定義了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就不再解釋了,比較簡單。