ApplicationContextAwareProcessor实现了BeanPostProcessor接口,BeanPostProcessor在前面我们已经介绍过可以参考Spring源码分析-IOC之BeanPostProcessor,所以在bean实例化的前后会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法,所以ApplicationContextAwareProcessor中也会有这两个方法,下面我们来看下具体的应用,首先继承ApplicationContextAware:
package com.ck.bean;
import java.io.Serializable;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class Person implements ApplicationContextAware, Serializable{
private static final long serialVersionUID = 1L;
private String name;
private ApplicationContext applicationContext;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void print() {
System.out.println("applicationContext:" + applicationContext);
}
}
看下配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<bean id="person" class="com.ck.bean.Person"/>
</beans>
测试类:
package com.ck.ioc;
import org.junit.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import com.ck.bean.Person;
public class IocTest {
@Test
public void test() {
ConfigurableApplicationContext ctx = new FileSystemXmlApplicationContext( "src/main/resources/applicationContext.xml");
Person person = ctx.getBean(Person.class);
person.print();
}
}
测试结果:
四月 15, 2019 6:15:00 下午 org.springframework.context.support.FileSystemXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@200a570f: startup date [Mon Apr 15 18:15:00 CST 2019]; root of context hierarchy
四月 15, 2019 6:15:01 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from file [X:\CK\stsws\springWeb\src\main\resources\applicationContext.xml]
applicationContext:org.springframework.context.support.FileSystemXmlApplicationContext@200a570f: startup date [Mon Apr 15 18:15:00 CST 2019]; root of context hierarchy
下面我们来看下源码:
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
//设置applicationContext属性
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@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);
return null;
}
}, acc);
}
else {
//从此方法处理
invokeAwareInterfaces(bean);
}
return bean;
}
//设置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);
}
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
private static class EmbeddedValueResolver implements StringValueResolver {
private final ConfigurableBeanFactory beanFactory;
public EmbeddedValueResolver(ConfigurableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public String resolveStringValue(String strVal) {
return this.beanFactory.resolveEmbeddedValue(strVal);
}
}
}
假若bean对象的类是ApplicationContextAware类型的话,就会调用invokeAwareInterfaces方法,将spring容器赋值给bean对象的applicationContext属性。