前言
bean的生命周期指的是 bean 的创建、初始化和销毁的过程。bean的创建是由容器完成的,但我们可以通过多种方式自定义bean的初始化和销毁的方法:容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
自定义初始化和销毁方法
① 通过@Bean指定init-method和destroy-method指定初始化和销毁方法;
@ComponentScan("com.atneusoft.bean") @Configuration public class MainConfigOfLifeCycle { @Bean(initMethod="init",destroyMethod="detory") public Car car(){ return new Car(); } }
同下
class="com.atneusoft.bean.Person" scope="prototype" destroy-method="" init-method="">
② 通过让Bean实现相关接口
InitializingBean(定义初始化逻辑),
DisposableBean(定义销毁逻辑);
public class Cat implements InitializingBean, DisposableBean { public Cat() { System.out.println("Cat constructor..."); } @Override public void afterPropertiesSet() throws Exception { System.out.println("cat afterPropertiesSet...."); } @Override public void destroy() throws Exception { System.out.println("cat destroy...."); } }
③可以使用JSR250注解指定具体的方法
@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
@PreDestroy:在容器销毁bean之前通知我们进行清理工作
public class Car{ public Cat() { System.out.println("Cat constructor..."); } @PostConstruct public void init() { System.out.println("cat 。。construct ...初始化之后。。。。。"); } @PreDestroy public void destroy(){ System.out.println("cat destroy 之前"); } }
BeanPostProcessor 接口
可以通过上面提到的三种方式进行bean的初始化方法
bean的后置处理器: 在bean初始化前后进行一些处理工作
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
注意:自定义bean的后置处理器将作用于所有的bean初始化前后,而bean的初始化方法只作用于当前bean
public class MyPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization " + beanName +"===>" + bean); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization " + beanName +"===>" + bean); return bean; } }
public interface BeanPostProcessor { /** * Apply this {@code BeanPostProcessor} to the given new bean instance before any bean * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} * or a custom init-method). The bean will already be populated with property values. * The returned bean instance may be a wrapper around the original. *The default implementation returns the given {
@code bean} as-is. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; * if {@code null}, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet */ @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /** * Apply this {@code BeanPostProcessor} to the given new bean instance after any bean * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} * or a custom init-method). The bean will already be populated with property values. * The returned bean instance may be a wrapper around the original. *In case of a FactoryBean, this callback will be invoked for both the FactoryBean * instance and the objects created by the FactoryBean (as of Spring 2.0). The * post-processor can decide whether to apply to either the FactoryBean or created * objects or both through corresponding {
@code bean instanceof FactoryBean} checks. *This callback will also be invoked after a short-circuiting triggered by a * {
@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method, * in contrast to all other {@code BeanPostProcessor} callbacks. *The default implementation returns the given {
@code bean} as-is. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; * if {@code null}, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet * @see org.springframework.beans.factory.FactoryBean */ @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
Bean的后置处理器的原理
自定义的bean的后置处理器,将自定义好的处理器置于容器当中,postProcessBeforeInitialization 方法处打断点,启动注解的方式spring容器,跟踪方法调用栈如下
@Configuration public class PostProcessConfig { @Bean public MyPostProcessor myPostProcessor(){ return new MyPostProcessor(); } }
@Test void Test01() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(PostProcessConfig.class); Cat cat = applicationContext.getBean(Cat.class); applicationContext.close(); System.out.println(cat); }
调用栈如下
创建bean的关键代码如下
try { populateBean(beanName, mbd, instanceWrapper);//为bean的各种属性赋值,在bean的始化之前完成 exposedObject = initializeBean(beanName, exposedObject, mbd);//初始化bean, }
初始化bean方法如下
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
applyBeanPostProcessorsBeforeInitialization的执行
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean;
//遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization
//一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
所有的bean处理器
Spring底层对BeanPostProcessor的使用
在Spring的底层,在bean的创建、初始化和赋值的过程当中大量的使用到了BeanPostProcess,常用的BeanPostProcessor:
①ApplicationContextAwareProcessor ====> 给容器中注入IOC 组件
@Nullable public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (!(bean instanceof EnvironmentAware) && !(bean instanceof EmbeddedValueResolverAware) && !(bean instanceof ResourceLoaderAware) && !(bean instanceof ApplicationEventPublisherAware) && !(bean instanceof MessageSourceAware) && !(bean instanceof ApplicationContextAware)) { return bean; } else { AccessControlContext acc = null; if (System.getSecurityManager() != null) { acc = this.applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null) { AccessController.doPrivileged(() -> { this.invokeAwareInterfaces(bean); return null; }, acc); } else { this.invokeAwareInterfaces(bean); } return bean; } } private void invokeAwareInterfaces(Object bean) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware)bean).setMessageSource(this.applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext); } }
如下进行IOC容器的注入
public class Color implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }
②AsyncAnnotationBeanPostProcessor ====》 处理@Async标注的异步方法
③AutowiredAnnotationBeanPostProcessor ====》对象创建完成以后,处理@Autowired标注的所有属性进行赋值
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
④BeanValidationPostProcessor ====》bean创建完,属性赋值以后(populateBean方法为给属性赋值)进行数据的校验
属性赋值==》数据校验==》初始化
public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean {
⑤InitDestroyAnnotationBeanPostProcessor ====》 处理@PostConstruct 、@PreDestroy注解
public class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable { /** * Specify the init annotation to check for, indicating initialization * methods to call after configuration of a bean. *Any custom annotation can be used, since there are no required * annotation attributes. There is no default, although a typical choice * is the JSR-250 {
@link javax.annotation.PostConstruct} annotation. */ public void setInitAnnotationType(Class extends Annotation> initAnnotationType) { this.initAnnotationType = initAnnotationType; } /** * Specify the destroy annotation to check for, indicating destruction * methods to call when the context is shutting down. *Any custom annotation can be used, since there are no required * annotation attributes. There is no default, although a typical choice * is the JSR-250 {
@link javax.annotation.PreDestroy} annotation. */ public void setDestroyAnnotationType(Class extends Annotation> destroyAnnotationType) { this.destroyAnnotationType = destroyAnnotationType; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//找到当前bean的生命周期注解标注的方法 LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try {
//利用反射调用bean的初始化方法 metadata.invokeInitMethods(bean, beanName); } catch (InvocationTargetException ex) { throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Failed to invoke init method", ex); } return bean; }
public void invokeInitMethods(Object target, String beanName) throws Throwable { CollectioncheckedInitMethods = this.checkedInitMethods; Collection initMethodsToIterate = (checkedInitMethods != null ? checkedInitMethods : this.initMethods); if (!initMethodsToIterate.isEmpty()) { for (LifecycleElement element : initMethodsToIterate) { if (logger.isTraceEnabled()) { logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod()); } element.invoke(target); } } }
@Component public class Dog implements ApplicationContextAware { //@Autowired private ApplicationContext applicationContext; public Dog(){ System.out.println("dog constructor..."); } //对象创建并赋值之后调用 @PostConstruct public void init(){ System.out.println("Dog....@PostConstruct..."); } //容器移除对象之前 @PreDestroy public void detory(){ System.out.println("Dog....@PreDestroy..."); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub this.applicationContext = applicationContext; } }
如上spring底层对 bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async等等都使用到了 BeanPostProcessor;
bean的生命周期总结
bean的生命周期:
bean创建---初始化----销毁的过程
容器管理bean的生命周期;
我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
构造(对象创建)
单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象
BeanPostProcessor.postProcessBeforeInitialization
初始化:
对象创建完成,并赋值好,调用初始化方法。。。
BeanPostProcessor.postProcessAfterInitialization
销毁:
单实例:容器关闭的时候
多实例:容器不会管理这个bean;容器不会调用销毁方法;