Bean生命周期
Bean生命周期可分为两个阶段:
- 初始化阶段:从初始化到准备完成可供使用;
- 销毁阶段:IoC容器shut down时销毁bean。
Aware接口
Aware接口在Spring框架自身应用比较多,开发者一般很少使用,下面三个比较熟知:
- BeanFactoryAware:提供setBeanFactory(), 为bean提供BeanFactory实例引用的回调方法;
- BeanNameAware:提供setBeanName() ,为bean提供name的回调方法;
- ApplicationContextAware:提供setApplicationContext(),为bean提供ApplicationContext实例引用的回调方法。
例如:
@Component
@ConfigurationProperties(prefix = "singer")
public class Singer implements ApplicationContextAware, BeanNameAware, BeanFactoryAware {
private String name;
private String beanName;
private BeanFactory beanFactory;
private ApplicationContext applicationContext;
//setter注入
public void setName(String name) {
this.name = name;
}
public void sing() {
System.out.println("singing,singing,singing...");
}
@Override
public void setBeanName(String s) {
this.beanName = s;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
BeanPostProcessor
BeanPostProcessor有两个方法,运行时,Spring会注入新的bean实例和bean name。
- postProcessBeforeInitialization:初始化之前的回调接口,在Aware的方法之后,初始化方法之前回调。
- postProcessAfterInitialization:任何初始化方法(如InitializingBean接口的afterPropertiesSet)之后回调。
这两个方法为容器提供配置bean的时机,不要随便使用。例如,实现这两个方法:
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor postProcessBeforeInitialization method is called : Bean Name " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor postProcessAfterInitialization method is called : Bean Name " + beanName);
return bean;
}
控制台输出非常多,每个bean都会打印一遍。
InitializingBean 和 DisposableBean
InitializingBean接口提供 afterPropertiesSet() 方法,用于自定义初始化逻辑,容器在bean属性设置完后调用。
DisposableBean接口提供 destroy() 方法,用于自定义bean的清理逻辑,在容器关闭后回调。
例如:
public class Singer implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean afterPropertiesSet method is called");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean destroy method is called");
}
}
为了看到destroy()方法,修改一下main:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
context.registerShutdownHook();
context.close();
}
}
总结
package com.example.demo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "singer")
public class Singer implements ApplicationContextAware, BeanNameAware, BeanFactoryAware, BeanPostProcessor, InitializingBean, DisposableBean {
private String name;
private String beanName;
private BeanFactory beanFactory;
private ApplicationContext applicationContext;
public Singer() {
System.out.println("Singer Constructor called");
}
//setter注入
public void setName(String name) {
this.name = name;
System.out.println("Singer setName called");
}
public void sing() {
System.out.println("singing,singing,singing...");
}
@Override
public void setBeanName(String s) {
System.out.println("BeanNameAware setBeanName method is called : Bean Name " + s);
this.beanName = s;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware setBeanFactory method is called : BeanFactory " + beanFactory);
this.beanFactory = beanFactory;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware setApplicationContext method is called : ApplicationContext " + applicationContext);
this.applicationContext = applicationContext;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor postProcessBeforeInitialization method is called : Bean Name " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor postProcessAfterInitialization method is called : Bean Name " + beanName);
return bean;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean afterPropertiesSet method is called");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean destroy method is called");
}
}
打印顺序是:
Singer Constructor called
BeanNameAware setBeanName method is called : Bean Name singer
BeanFactoryAware setBeanFactory method is called : BeanFactory org.springframework.beans.factory.support.DefaultListableBeanFactory@2203bc9e:
ApplicationContextAware setApplicationContext method is called : ApplicationContext org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@37ee642c
Singer setName called
BeanPostProcessor postProcessBeforeInitialization method is called : Bean Name
InitializingBean afterPropertiesSet method is called
BeanPostProcessor postProcessAfterInitialization method is called : Bean Name
DisposableBean destroy method is called