功能特性
ApplicationContextAwareProcessor本身并不是扩展点,而是实现了BeanPostProcessor,并实现postProcessBeforeInitialization(),所以并不需要去实现它,但是其内部包含了以下6个接口实现的执行时机,这几个接口的功能作用分别是:
EnvironmentAware:用于获取Enviroment,Enviroment可以获得系统内的所有参数;另外也可以通过注入的方式来获得Environment,用哪种方式需要以实现场景而决定。
EmbeddedValueResolverAware:用于获取StringValueResolver,StringValueResolver可以获取基于String类型的properties的变量;另外还可以使用@Value的方式来获取properties的变量,用哪种方式需要以实现场景而决定。
ResourceLoaderAware:用于获取ResourceLoader,ResourceLoader可以用于获取classpath内所有的资源对象。
ApplicationEventPublisherAware:用于获取ApplicationEventPublisher,ApplicationEventPublisher可以用来发布事件,当然这个对象也可以通过spring注入的方式来获得,具体的实现方式可以参考Springboot事件监听机制的实战应用。
MessageSourceAware:用于获取MessageSource,MessageSource主要用来做国际化。
ApplicationContextAware:用来获取ApplicationContext,ApplicationContext就是Spring上下文管理器。
下面定义一个Bird类,实现ApplicationContextAware接口,以Bird为例分享ApplicationContextAwareProcessor的功能特性。
@Component
@Slf4j
public class Bird implements ApplicationContextAware {
private String name="xiao niao";
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
log.info("----Spring的上下文环境application被注入");
}
}
@Test
public void test3(){
log.info("----单元测试执行开始");
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.fanfu");
log.info("----单元测试执行完毕");
}
单元测执行结果
图片
工作原理
注册时机
ApplicationContextAwareProcessor的注册时机,即准备BeanFactory的时候,注册的入口在AbstractApplicationContext#refresh----->AbstractApplicationContext#prepareBeanFactory方法中。
图片
执行逻辑
ApplicationContextAwareProcessor#postProcessBeforeInitialization的扩展逻辑很简单:即当前Bean是否实现了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware,如果不是,则直拉返回,如果是,则执行XxxAware接口的扩展逻辑;
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//如果非实现EnvironmentAware、EmbeddedValueResolverAware、
//ResourceLoaderAware、ApplicationEventPublisherAware、
//MessageSourceAware、ApplicationContextAware,则直拉返回;
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction
执行时机
因为ApplicationContextAwareProcessor实现了BeanPostProcessor接口,并重写了postProcessBeforeInitialization()。关于BeanPostProcessor接口的执行时机可移步Springboot扩展点之BeanPostProcessor,这里就不再反复赘述了。
图片
总结
通过以上的分析,可以了解到:
ApplicationContextAwareProcessor实现BeanPostProcessor接口,是Spring扩展点之BeanPostProcessor的内部经典实现。
ApplicationContextAwareProcessor#postProcessBeforeInitialization内部逻辑很简单,主要是执行了XxxAware相关扩展接口具体实现;
ApplicationContextAwareProcessor注册时机相对比较早,即BeanFactory实例化后,相关属性初始化时;
ApplicationContextAwareProcessor#postProcessBeforeInitialization的执行时机,是在Spring管理的Bean实例化、属性注入完成后,InitializingBean#afterPropertiesSet方法以及自定义的初始化方法之前;