【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 联系我们: