Spring源码分析-IOC之ApplicationContextAwareProcessor

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属性。

猜你喜欢

转载自blog.csdn.net/cgsyck/article/details/89317704