Spring回调接口Aware-源码分析


title: Spring回调接口Aware-源码分析
date: 2020-04-24 21:37:27
tags:


Spring提供了一种机制,让bean在实例化的时候,能够感知(获取)容器中的一些组件,即Aware接口回调的方式。这种机制一般是Spring框架内部使用。

Aware z作用
BeanFactoryAware 获取当前 BeanFactory,这样可以调用容器的服务
ApplicationContextAware t同BeanFactory
MessageSourceAware 获取 Message Source 相关文本信息
ApplicationEventPublisherAware 发布事件
ResourceLoaderAware 获取资源加载器,这样获取外部资源文件
BeanNameAware 获取容器中 Bean 的名称

示例

@Component
public class AwareTest implements ApplicationContextAware , BeanNameAware {
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("取得applicationContext。。。。");
    }

    public void setBeanName(String name) {
        System.out.println(name);
    }
}

原理

在这些Aware中,底层实现主要分为两种:

  • invokeAwareMethods(beanName, bean);

  • BeanPostProcessor

(1)invokeAwareMethods(beanName, bean);

在创建bean的核心方法initializeBean中,创建好bean后,都会先调用invokeAwareMethods(beanName, bean);,再进行初始化。

若这个bean为一个Aware,就去尝试调用一些回调方法。

在这个方法中,有三种Aware会在这个方法中被调用:BeanNameAwareBeanClassLoaderAwareBeanFactoryAware

//
if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}

(2)BeanPostProcessor

其余的Aware是由BeanPostProcessor来实现的,xxxAware都有一个xxxAwareProcessor与之对应,例如ApplicationAware-----ApplicationAwareProcessor

在Spring Bean的创建初始化过程–源码分析中,我们已经说过beanPostProcessor的前置处理都是在applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)中被一一执行。

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            //调用postProcessBeforeInitialization
			Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

ApplicationAwareProcessor为例,经过一些安全验证,最终会调用invokeAwareInterfaces(bean)

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((PrivilegedAction<Object>) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

逻辑也很简单,判断这个Aware是哪个Aware,就强制转换调用。

	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(this.embeddedValueResolver);
			}
			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);
			}
		}
	}

你可能感兴趣的:(Spring)