ApplicationContextAware,ServletContextAware等Aware接口的理解
程序员文章站
2022-03-08 10:03:38
...
Aware接口理解
Aware的意思是感知
ApplicationContextAware可以获得 ApplicationContext上下文资源
ServletContextAware可以获得ServletContext上下文资源
…
实现xxAware接口的子类,会覆盖对应的setXX()方法,从而可以获得Spring容器中的xx资源
ApplicationContextAware实例
ApplicationContextAware接口,可以在Spring初始化实例 Bean的时候,可以通过这个接口将当前的Spring上下文传入。
注意:一定要让继承ApplicationContextAware接口的bean被Spring上下文管理
在application.xml文件中定义对应的bean标签,或者使用@Component标注。
@Component
public class Test implements ApplicationContextAware,ServletContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println(applicationContext);
}
@Override
public void setServletContext(ServletContext servletContext) {
System.out.println(servletContext);
}
}
我们看到实现ApplicationContextAware只覆盖了一个setApplicationContext方法
而这个方法在初始化时会注入ApplicationContext供子类Test设置
SpringBean初始化流程
debug代码我们发现ApplicationContextAwareProcessor的invokeAwareInterfaces上下文被注入,注入逻辑很简单,如果是ApplicationContextAware的实例,就set进去
if (bean instanceof Aware) {
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);
}
}
调用堆栈
setApplicationContext:21, Test (com.microptech.eurekaregistry)
invokeAwareInterfaces:120, ApplicationContextAwareProcessor (org.springframework.context.support)
postProcessBeforeInitialization:96, ApplicationContextAwareProcessor (org.springframework.context.support)
applyBeanPostProcessorsBeforeInitialization:419, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1737, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:576, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:498, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:320, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 23880693 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$139)
getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:318, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:199, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:846, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:863, AbstractApplicationContext (org.springframework.context.support)
refresh:546, AbstractApplicationContext (org.springframework.context.support)
refresh:142, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
refresh:775, SpringApplication (org.springframework.boot)
refreshContext:397, SpringApplication (org.springframework.boot)
run:316, SpringApplication (org.springframework.boot)
run:1260, SpringApplication (org.springframework.boot)
run:1248, SpringApplication (org.springframework.boot)
main:12, EurekaRegistryApplication (com.microptech.eurekaregistry)
Spring实例WebMvcConfigurationSupport
以WebMVC比较核心的ServletContext类为例
WebMvcConfigurationSupport
通过继承ApplicationContextAware和ServletContextAware 接口
可以通过ApplicationContext,ServletContext实现获取spring配置文件,设置异常处理器等功能
public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
@Override
public void setApplicationContext(@Nullable ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public void setServletContext(@Nullable ServletContext servletContext) {
this.servletContext = servletContext;
}
}