Aware概述
Aware是Spring提供的一个标记超接口,它里面什么也没有,它主要重要就是向我们提供一种资源访问的入口标记而已,在spring中内置了9个Aware抽象。今天我们主要就来了解一下这9个Aware以及他们是如何工作的。
package org.springframework.beans.factory;
public interface Aware {
}
Aware内置接口
|--Aware
|--BeanNameAware
|--BeanClassLoaderAware
|--BeanFactoryAware
|--EnvironmentAware
|--EmbeddedValueResolverAware
|--ResourceLoaderAware
|--ApplicationEventPublisherAware
|--MessageSourceAware
|--ApplicationContextAware
BeanNameAware
BeanNameAware是Spring框架中提供的一个接口,用于让一个Bean在容器中意识到自己的Bean名称。通过实现BeanNameAware接口,一个Bean可以在初始化阶段访问到它被分配的名称。这对于那些需要根据自己在应用程序上下文中的名称执行特定操作的Bean非常有用。
package org.springframework.beans.factory;
public interface BeanNameAware extends Aware {
void setBeanName(String var1);
}
BeanClassLoaderAware
BeanClassLoaderAware是Spring框架中提供的另一个接口。它允许一个Bean意识到用于加载该Bean类的类加载器。通过实现BeanClassLoaderAware接口,一个Bean可以在初始化阶段访问类加载器。这对于需要基于类加载器执行操作的Bean非常有用,比如动态类加载或资源加载。
package org.springframework.beans.factory;
public interface BeanClassLoaderAware extends Aware {
void setBeanClassLoader(ClassLoader var1);
}
BeanFactoryAware
BeanFactoryAware是Spring框架中提供的一个接口。它允许一个Bean意识到创建和管理该Bean的Bean工厂。通过实现BeanFactoryAware接口,一个Bean可以在初始化阶段访问工厂。这对于需要与工厂进行交互的Bean非常有用,例如获取其他Bean或访问配置信息。
package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory var1) throws BeansException;
}
EnvironmentAware
EnvironmentAware是Spring框架中提供的一个接口。它允许一个Bean意识到它所运行的应用程序环境。通过实现EnvironmentAware接口,一个Bean可以在初始化阶段访问环境。这对于需要访问特定于环境的信息的Bean非常有用,例如属性、配置文件或活动配置文件,以便根据运行时环境自定义它们的行为。
package org.springframework.context;
import org.springframework.beans.factory.Aware;
import org.springframework.core.env.Environment;
/**
* Interface to be implemented by any bean that wishes to be notified
* of the {@link Environment} that it runs in.
*
* @author Chris Beams
* @since 3.1
*/
public interface EnvironmentAware extends Aware {
/**
* Set the {@code Environment} that this object runs in.
*/
void setEnvironment(Environment environment);
}
EmbeddedValueResolverAware
EmbeddedValueResolverAware是Spring框架中提供的一个接口。它允许一个Bean意识到用于解析bean定义中占位符和表达式的嵌入式值解析器。通过实现EmbeddedValueResolverAware接口,一个Bean可以在初始化阶段访问值解析器。这对于需要根据运行时值解析属性或配置中的占位符或表达式的Bean非常有用。
package org.springframework.context;
import org.springframework.beans.factory.Aware;
import org.springframework.util.StringValueResolver;
/**
* Interface to be implemented by any object that wishes to be notified of a
* <b>StringValueResolver</b> for the <b> resolution of embedded definition values.
*
* <p>This is an alternative to a full ConfigurableBeanFactory dependency via the
* ApplicationContextAware/BeanFactoryAware interfaces.
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 3.0.3
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#resolveEmbeddedValue
*/
public interface EmbeddedValueResolverAware extends Aware {
/**
* Set the StringValueResolver to use for resolving embedded definition values.
*/
void setEmbeddedValueResolver(StringValueResolver resolver);
}
ResourceLoaderAware
ResourceLoaderAware是Spring框架中提供的一个接口。它允许一个Bean意识到资源加载器,用于加载外部资源文件。通过实现ResourceLoaderAware接口,一个Bean可以在初始化阶段访问资源加载器。这对于需要加载外部资源文件的Bean非常有用,例如配置文件、模板文件等。
package org.springframework.context;
import org.springframework.beans.factory.Aware;
import org.springframework.core.io.ResourceLoader;
public interface ResourceLoaderAware extends Aware {
void setResourceLoader(ResourceLoader resourceLoader);
}
ApplicationEventPublisherAware
ApplicationEventPublisherAware是Spring框架中提供的一个接口。它允许一个Bean意识到应用事件发布器。通过实现ApplicationEventPublisherAware接口,一个Bean可以在初始化阶段访问事件发布器。这对于需要发布应用事件或与Spring中的事件系统进行交互的Bean非常有用。
package org.springframework.context;
import org.springframework.beans.factory.Aware;
public interface ApplicationEventPublisherAware extends Aware {
void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher);
}
MessageSourceAware
MessageSourceAware是Spring框架中提供的一个接口。它允许一个Bean意识到消息源,消息源负责解析本地化消息。通过实现MessageSourceAware接口,一个Bean可以在初始化阶段访问消息源。这对于需要获取本地化消息或根据不同的语言环境执行消息解析的Bean非常有用。
package org.springframework.context;
import org.springframework.beans.factory.Aware;
public interface MessageSourceAware extends Aware {
void setMessageSource(MessageSource messageSource);
}
ApplicationContextAware
ApplicationContextAware是Spring框架中提供的一个接口。它允许一个Bean意识到应用程序上下文,也就是Spring容器。通过实现ApplicationContextAware接口,一个Bean可以在初始化阶段访问应用程序上下文。这对于需要与容器进行交互或获取其他Bean的Bean非常有用。
package org.springframework.context;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.Aware;
public interface ApplicationContextAware extends Aware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
Aware在Spring中的调用时机
首先9类Aware在Spring中分成了2类,BeanNameAware、BeanClassLoaderAware、BeanFactoryAware三个为一组在初始化前直接调用,其余6个为一组通过ApplicationContextAwareProcessor后置处理器,在初始化后间接回调。通过Spring创建bean代码跟中我们找到初始化方法。
invokeAwareMethods
在invokeAwareMethods中根据创建bean对象继承接口进行对应资源的植入
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware)bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware)bean).setBeanFactory(this);
}
}
}
applyBeanPostProcessorsBeforeInitialization
这里是后置处理器BeanPostProcessor统一调用入口,当然这也包括ApplicationContextAwareProcessor后置处理器
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Iterator i$ = this.getBeanPostProcessors().iterator();
do {
if (!i$.hasNext()) {
return result;
}
BeanPostProcessor beanProcessor = (BeanPostProcessor)i$.next();
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
} while(result != null);
return result;
}
ApplicationContextAwareProcessor
便于阅读理解只保留了相关方法内容,首先我们很容易发现它是实现了后置处理器接口BeanPostProcessor,并实现了方法postProcessBeforeInitialization。所以才有上面我们说得它在bean的初始化方法前调用。
package org.springframework.context.support;
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
invokeAwareInterfaces(bean);
return null;
}
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
}
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);
}
}
}
}
ApplicationContextAwareProcessor又在哪示例化的呢?
在日常开发过程中文我们也没有对ApplicationContextAwareProcessor进行实例化,它是在什么时候进入到Spring容器中的呢?思考两分钟我们揭秘
AbstractApplicationContext.refresh刷新容器的时候,有个叫prepareBeanFactory的方法执行一些bean工厂的准备工作,在里面
在这里我们找到了Spring容器中添加ApplicationContextAwareProcessor后置处理器的入口
总结
到目前为止我们了解9中Spring内置Aware接口,并且他们分两种方式在bean初始化之前被调用。聪明的小伙伴一定和我一样有个疑问,明明两种方式都能达到目的,为什么不用一个?