Spring生命周期回调与容器扩展详解
在Spring框架中,Bean的生命周期回调与容器扩展是非常重要的一部分。Spring框架有一个完整的标准初始化和销毁Bean的流程, 我们可以根据自己的业务需求去扩展这个流程,实现一些自定义的处理。
Bean的生命周期回调
在Spring中,一个Bean的创建与销毁都是由容器来管理的, 容器会自动的调用Bean的一些方法来完成Bean的初始化和销毁。我们可以在Bean的生命周期的多个阶段插入我们自己的处理逻辑。这些阶段包括:Bean实例化、Bean属性设置、Bean初始化前、Bean初始化后、容器销毁前和容器销毁后等。
Bean实例化
在Bean实例化阶段,Spring会通过调用Bean的构造方法来实例化一个对象。如果Bean类的构造方法中存在参数,则Spring会先通过它们来实例化出所需的参数,并进行递归实例化。接着Spring会调用Bean实例化回调接口:InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法,以便让用户在Bean实例化之前进行一些处理。如果该方法返回了非 null 的 Bean,则 Spring 容器将不再调用它后面的 Bean 构造方法,直接使用返回的 Bean 对象。如果该方法返回了 null,则 Spring 容器仍会继续进行 Bean 的构造方法调用,直到构造出实例为止。
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if ("user".equals(beanName)) {
System.out.println("InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation");
}
return null;
}
}
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
@Bean
public MyInstantiationAwareBeanPostProcessor myInstantiationAwareBeanPostProcessor() {
return new MyInstantiationAwareBeanPostProcessor();
}
}
Bean属性设置
在Bean属性设置阶段,Spring会调用Bean的setter方法来完成依赖注入。Spring通过反射机制查找 Bean 中特定的 set 方法,并将配置文件或者注释配置中所定义的属性值通过这些set方法进行注入。如果Bean实现了BeanNameAware接口或BeanFactoryAware接口,则在属性注入完成后,Spring容器会调用相应的回调方法:BeanNameAware#setBeanName()或BeanFactoryAware#setBeanFactory()。
public class User implements BeanNameAware, BeanFactoryAware {
private String name;
private int age;
public void setBeanName(String name) {
System.out.println(this.getClass().getSimpleName() + " setBeanName");
}
public void setBeanFactory(BeanFactory beanFactory) {
System.out.println(this.getClass().getSimpleName() + " setBeanFactory");
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
@Bean
public User user() {
User user = new User();
user.setName("Nate");
user.setAge(30);
return user;
}
}
Bean初始化前
在Bean初始化前阶段,Spring容器会调用BeanPostProcessor#postProcessBeforeInitialization()该回调方法,让用户可以在Bean初始化的前面添加自己的逻辑。 Spring容器必须在Bean属性注入完成后,Bean实现了Aware的回调方法后,才会回调这个 BeanPostProcessor 的回调方法。这可以保证调用之前的 Bean 所有属性都被正确的设置了。
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("user".equals(beanName)) {
System.out.println("BeanPostProcessor postProcessBeforeInitialization");
}
return bean;
}
}
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
@Bean
public MyBeanPostProcessor myBeanPostProcessor() {
return new MyBeanPostProcessor();
}
}
Bean初始化后
在Bean初始化后阶段,Spring容器会调用BeanPostProcessor#postProcessAfterInitialization()该回调方法,让用户可以在Bean初始化的后面添加自己的逻辑。 Spring容器必须在调用BeanPostProcessor#postProcessBeforeInitialization()之后,才会回调这个 BeanPostProcessor 的回调方法。
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("user".equals(beanName)) {
System.out.println("BeanPostProcessor postProcessAfterInitialization");
}
return bean;
}
}
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
@Bean
public MyBeanPostProcessor myBeanPostProcessor() {
return new MyBeanPostProcessor();
}
}
容器销毁前
在容器销毁前阶段,Spring容器会调用DisposableBean#destroy()方法和DestroyBean接口的destroy()方法,以便进行Bean销毁前的一些逻辑处理。
public class Dog implements DisposableBean {
public void destroy() throws Exception {
System.out.println("DisposableBean destroy");
}
}
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
@Bean(destroyMethod = "destroy")
public Dog dog() {
return new Dog();
}
}
容器销毁后
在容器销毁后阶段,Spring容器会调用BeanPostProcessor#postProcessBeforeDestruction()方法和DestroyBean接口的destroy()方法,以便进行销毁Bean后的一些逻辑处理。
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if ("user".equals(beanName)) {
System.out.println("DestructionAwareBeanPostProcessor postProcessBeforeDestruction");
}
}
public boolean requiresDestruction(Object bean) {
return true;
}
}
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
@Bean
public MyDestructionAwareBeanPostProcessor myDestructionAwareBeanPostProcessor() {
return new MyDestructionAwareBeanPostProcessor();
}
}
容器扩展
在Spring中,我们还可以通过继承一些扩展点的抽象类来实现我们自己的扩展。这些扩展点包括:BeanFactoryPostProcessor、BeanPostProcessor、ApplicationListener和ResourceLoaderAware等。
BeanFactoryPostProcessor
BeanFactoryPostProcessor用于对BeanFactory进行处理。在Spring容器初始化完成之后,BeanFactory 调用BeanFactoryPostProcessor回调函数对BeanFactory进行外部扩展。我们可以通过实现这个接口实现对Bean的修改,比如替换Bean的内容,增加Bean的内容等等。注意:这个扩展只是针对BeanFactory的扩展,而不是Bean的扩展。
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition bd = beanFactory.getBeanDefinition("dog");
MutablePropertyValues pvs = bd.getPropertyValues();
if (pvs.contains("name")) {
PropertyValue pv = pvs.getPropertyValue("name");
pv.setConvertedValue("Tommy");
}
}
}
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
@Bean
public MyBeanFactoryPostProcessor myBeanFactoryPostProcessor() {
return new MyBeanFactoryPostProcessor();
}
}
BeanPostProcessor
前面已经讲解了BeanPostProcessor,它主要用于在Bean的初始化前后添加自己的处理逻辑。
ApplicationListener
ApplicationListener用于监听ApplicationEvent类型的事件。当相关事件发生时,Spring容器就会调用该接口的回调函数。我们可以利用这个机制自定义自己需要的事件,并在事件发生时实现自己的业务逻辑。
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
public void onApplicationEvent(MyApplicationEvent event) {
System.out.println("MyApplicationListener onApplicationEvent");
}
}
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
@Bean
public MyApplicationListener myApplicationListener() {
return new MyApplicationListener();
}
}
public class MyApplicationEvent extends ApplicationEvent {
public MyApplicationEvent(Object source) {
super(source);
}
}
@Component
public class User {
@Autowired
private ApplicationContext applicationContext;
public void print() {
MyApplicationEvent event = new MyApplicationEvent(this);
applicationContext.publishEvent(event);
}
}
ResourceLoaderAware
ResourceLoaderAware用于在加载Bean时获取ResourceLoader(资源加载器)来加载文件或URL等资源。
public class MyResourceLoaderAware implements ResourceLoaderAware {
private ResourceLoader resourceLoader;
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public void print() throws IOException {
Resource resource = resourceLoader.getResource("classpath:test.txt");
InputStream inputStream = resource.getInputStream();
System.out.println(inputStream);
}
}
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
@Bean
public MyResourceLoaderAware myResourceLoaderAware() {
return new MyResourceLoaderAware();
}
}
总结
Spring中的Bean生命周期回调和容器扩展提供了很好的扩展机制, 通过实现一些扩展点的接口,我们可以在Bean的实例化,初始化,销毁的不同阶段插入我们自己的处理逻辑,实现一些自定义的处理。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring生命周期回调与容器扩展详解 - Python技术站