Spring注解驱动开发——bean的后置处理器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rubulai/article/details/80413559

BeanPostProcessor:是一个接口,bean的后置处理器(实际是在bean的初始化前后执行操作)

public class MyBeanPostProcessor implements BeanPostProcessor{

	/**
	 * bean是容器调用构造器创建的实例
	 * beanName是实例的id
	 * 在所有初始化方法之前调用
	 */
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	
	/**
	 * bean是容器调用构造器创建的实例
	 * beanName是实例的id
	 * 在所有初始化方法之后调用
	 */
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
}

将MyBeanPostProcessor纳入到容器中:

@Configuration
@Import(MyBeanPostProcessor.class)
public class LifeCycleConfig {

	@Bean(initMethod="init0",destroyMethod="destroy0")
	public Car car(){
		return new Car();
	}
}

这样该容器中的所有bean在初始化前后都会执行该后置处理器中的逻辑,即使未定义初始化方法这些逻辑也会执行的,由此可以猜测:BeanPostProcessor可能是面向切面的

通过查看源码,整个逻辑是这样的:

在调用构造器之后,会为对象的所有属性赋值,赋值完成后会调用初始化方法,但是在调用初始化方法时会进入一个切面,完成在初始化的前后执行BeanPostProcessor的逻辑:容器会遍历所有的BeanPostProcessor并依次执行每个后置处理器的前置方法(postProcessBeforeInitialization),直至全部执行完或者其中一个该类方法返回null,然后完成Bean的初始化,初始化完成后,容器会继续遍历执行所有的BeanPostProcessor的后置方法(postProcessAfterInitialization),直至全部执行完或者其中一个该方法返回null

JDK1.8之后interface也可以有方法体了,子类也可以不实现接口中已有方法体的方法:

public interface BeanPostProcessor {

	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

BeanPostProcessor在Spring底层的使用:

组件通过实现ApplicationContextAware接口获取IOC容器,其实是ApplicationContextAwareProcessor在起作用

@Component
public class ContextBean implements ApplicationContextAware {

	private ApplicationContext context;

	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		context = applicationContext;
	}
}

怎么获取到的IOC容器呢?容器在调用Bean的构造器并给所有属性赋值之后,在执行所有初始化方法之前和之后,会执行一些BeanPostProcessor接口的子类中的逻辑,比如ApplicationContextAwareProcessor,在执行ApplicationContextAwareProcessor的postProcessBeforeInitialization()方法时,会判断Bean是否实现了ApplicationContextAware接口,然后注入相应的ApplicationContext容器给Bean使用

②对组件的属性进行校验的BeanValidationPostProcessor

InitDestroyAnnotationBeanPostProcessor:扫描Bean中标注了@PostConstruct和@PreDestroy注解的方法并执行,这也就是为什么@PostConstruct标注的初始化方法在其他初始化方法之前执行

AutowiredAnnotationBeanPostProcessor:为bean中标注了@Autowired注解的属性赋值,这就是为什么可以在init()方法中使用@Autowired注解的属性的原因,因为在调用init方法之前会将这些属性的值注入

⑤AsyncAnnotationBeanPostProcessor:使标注了@Async的方法异步执行

猜你喜欢

转载自blog.csdn.net/rubulai/article/details/80413559