深入理解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,那么这玩意干了什么事情呢?我们一起来看下它的代码:

@Override

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>() {

@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

回到顶部