深入理解Spring IOC之扩展篇(四)、Aware接口
本篇讲的是Spring中的Aware接口,也应该是整个系列中最简单的一篇了,但是简单并不代表这玩意不重要,我们很多时候还是会用Aware接口去为我们做事情的。
我们知道,使用了Spring容器之后,我们创建对象这件事情完完全全的交给了Spring,在创建好了之后我们直接拿来用就可以了,容器内的东西对于我们的bean来说完全是透明的。为了让我们的bean可以感知到容器内的一些东西,所以Spring为我们提供了Aware接口,看过我之前文章的小伙伴肯定都知道,在初始化bean的时候有这么一段代码:
private void invokeAwareMethods(final String beanName, final Object bean) {// 所谓的xxxAware,就是让这个bean和xxx产生关联
if (bean instanceof Aware) {
// 设置名称
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// 类加载器
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
// 我们有时候使用BeanFactoryAware去拿BeanFactory,就是在这步设置的
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
上面这段代码便是处理其中三种Aware的逻辑,我们分别看看这三种Aware的代码:
BeanNameAware:
public interface BeanNameAware extends Aware {void setBeanName(String name);
}
BeanClassLoaderAware:
public interface BeanClassLoaderAware extends Aware {void setBeanClassLoader(ClassLoader classLoader);
}
BeanFactoryAware:
public interface BeanFactoryAware extends Aware {void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
这三个Aware其实也就是让我们的bean可以知道自己名字,自己的ClassLoader是哪个,加载自己的BeanFactory是哪个,结合我们上面的代码我们知道其实设置这三个Aware是在bean的生命周期内设置的。
那么还有哪些常见的Aware呢?我自己最常用的一个就是ApplicationContextAware,这个接口的代码我就不贴出来了,因为和上面是一样的,就一个set方法而已,那么又是在哪个地方给我们的bean执行了setApplicationContext的方法呢?我们之前文章中介绍AbstractApplicationContext的refresh方法的时候,其中有个prepareBeanFactory方法,这个方法中有这么一句代码:
只看画红框的地方就行了,我们可以看到,spring在这里增加了一个ApplicationContextAwareProcessor,这个玩意的本质上是个BeanPostProcessor,那么这玩意干了什么事情呢?我们一起来看下它的代码:
@Overridepublic 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>() {
@Override
public Object run() {
invokeAwareInterfaces(bean);
returnnull;
}
}, 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);
}
}
}
这个类只是实现了前置处理这个方法,前置处理什么时候执行的我就不说了,看到这里的人应该是清楚的。这段代码你看我连注释都很少,因为真的很简单,就是检测你是不是实现了这个Aware接口,如果实现了,就给你set上相应的对象而已。其中invokeAwareInterfaces中还有几个其他的Aware,但是说真的,这几个用的都不多,我自己都很少见过业务中使用这几个的,如果读者有兴趣可以自己研究下这几个。
以上是 深入理解Spring IOC之扩展篇(四)、Aware接口 的全部内容, 来源链接: utcz.com/a/27956.html