Spring源码阅读-Aware接口

原创
2017/06/02 10:23
阅读数 519

一、介绍

spring中提供了一些以Aware结尾的接口:

实现这些接口的类在被实例化后可以获得对应的系统内部对象,比如实现BeanFactoryAware接口可以获得BeanFactory对象。

二、举例

以获得BeanFactory和ApplicationContext为例举例说明Aware接口的使用:

public class School implements ApplicationContextAware, BeanFactoryAware {

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("======" + beanFactory);

	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		System.out.println("======" + applicationContext);

	}
}

实现Aware接口后会要求实现对应的setter方法。

三、原理

这个功能也是基于BeanPostProcessor来实现的,搜索*AwareProcessor都是来实现不同Aware注入的,以ApplicationContextAwareProcessor为例说明:

class ApplicationContextAwareProcessor implements BeanPostProcessor {

	private final ConfigurableApplicationContext applicationContext;

	/**
	 * Create a new ApplicationContextAwareProcessor for the given context.
	 */
	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;
	}
	// 这里是核心逻辑
	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			//实现了对应的Aware就调用对应的setter方法
			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);
			}
		}
	}



}

实现逻辑很简单,就判断对象实现了什么接口就调用对应的setter方法,更重要的是看postProcessBeforeInitialization是在什么地方被调用的,反推方法定位到doCreateBean流程中,在填充对象完毕和调用初始化方法之间调用了postProcessBeforeInitialization方法。

 

上面的功能也可以通过@Autowired注解实现,都是注入。

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部