【spring mvc】application context中【bean】的生命周期


  • 生命周期過程

主要分為四部分:

一、實例化

1. 當調用者通過 getBean( name )向 容器尋找Bean 時,如果容器注冊了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,在實例 bean 之前,將調用該接口的 postProcessBeforeInstantiation ()方法。
2. 根據配置情況調用 Bean構造函數或工廠方法實例化 bean。
3. 如果容器注冊了 org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,在實例 bean 之后,調用該接口的 postProcessAfterInstantiation ()方法,可以在這里對已經實例化的對象進行一些裝飾。
4. 受用依賴注入,Spring 按照 Bean 定義信息配置 Bean 的所有屬性 ,在設置每個屬性之前將調用InstantiationAwareBeanPostProcess接口的 postProcessPropertyValues ()方法 。
5 .如果Bean實現了BeanNameAware接口,會回調該接口的setBeanName()方法,傳入該Bean的id,此時該Bean就獲得了自己在配置文件中的id。
6 .如果Bean實現了BeanFactoryAware接口,會回調該接口的setBeanFactory()方法,傳入該Bean的BeanFactory,這樣該Bean就獲得了自己所在的BeanFactory。
7、如果Bean實現了ApplicationContextAware接口,會回調該接口的setApplicationContext()方法,傳入該Bean的ApplicationContext,這樣該Bean就獲得了自己所在的ApplicationContext。

二、初始化

8.如果有Bean實現了BeanPostProcessor接口,則會回調該接口的postProcessBeforeInitialzation()方法對 bean進行加工操作,這個非常重要, spring 的 AOP 就是用它實現的

9.如果Bean實現了InitializingBean接口,則會回調該接口的afterPropertiesSet()方法,實現 InitializingBean接口必須實現afterPropertiesSet方法。(這個方法的作用是啥,還不太清楚)

10.如果Bean配置了init-method方法,則會執行init-method配置的方法。

11.如果有Bean實現了BeanPostProcessor接口,則會回調該接口的postProcessAfterInitialization()方法。

三、執行具體的操作

12.經過流程9之后,就可以正式使用該Bean了,對於scope為singleton的Bean,Spring的ioc容器中會緩存一份該bean的實例,而對於scope為prototype的Bean,每次被調用都會new一個新的對象,期生命周期就交給調用方管理了,不再是Spring容器進行管理了。

然后就可以用這個Bean想干啥干啥了。。。

四、銷毀

13.容器關閉后,如果Bean實現了DisposableBean接口,則會回調該接口的destroy()方法。

14.如果Bean配置了destroy-method方法,則會執行destroy-method配置的方法,至此,整個Bean的生命周期結束。

  • 代碼解析

示例代碼地址:https://github.com/handv/SpringMVCDemo/tree/master/SpringMVC_000

代碼執行結果:

開始初始化容器
九月 25, 2016 10:44:50 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@b4aa453: startup date [Sun Sep 25 22:44:50 CST 2016]; root of context hierarchy 九月 25, 2016 10:44:50 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [com/test/spring/life/applicationContext.xml] Person類構造方法 set方法被調用 setBeanName被調用,beanName:person1 setBeanFactory被調用,beanFactory setApplicationContext被調用 postProcessBeforeInitialization被調用 afterPropertiesSet被調用 myInit被調用 postProcessAfterInitialization被調用 xml加載完畢 name is :jack 關閉容器 九月 25, 2016 10:44:51 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose 信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@b4aa453: startup date [Sun Sep 25 22:44:50 CST 2016]; root of context hierarchy destory被調用 myDestroy被調用

1、AbstractAutowireCapableBeanFactory.populateBean

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { ... if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { //這里用到了InstantiationAwareBeanPostProcessor if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //這里用到了postProcessAfterInstantiation方法 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } ... boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) {  //注冊InstantiationAwareBeanPostProcessor接口  if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  //調用InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法  pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } //該處反射執行Bean的setxxx方法 applyPropertyValues(beanName, mbd, bw, pvs); }

2、AbstractAutowireCapableBeanFactory.invokeAwareMethods()

private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) {  //設置BeanName  ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } if (bean instanceof BeanFactoryAware) {  //設置BeanFactory  ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }

3、AbstractAutowireCapableBeanFactory.initializeBean

/** * Initialize the given bean instance, applying factory callbacks * as well as init methods and bean post processors. * <p>Called from {@link #createBean} for traditionally defined beans, * and from {@link #initializeBean} for existing bean instances. * @param beanName the bean name in the factory (for debugging purposes) * @param bean the new bean instance we may need to initialize * @param mbd the bean definition that the bean was created with * (can also be {@code null}, if given an existing bean instance) * @return the initialized bean instance (potentially wrapped) * @see BeanNameAware * @see BeanClassLoaderAware * @see BeanFactoryAware * @see #applyBeanPostProcessorsBeforeInitialization * @see #invokeInitMethods * @see #applyBeanPostProcessorsAfterInitialization */ protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { 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; }

后續代碼可以看源碼的注釋,先不看了,太多了

參考:http://www.jianshu.com/p/3944792a5fff


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: