spring之aware接口

2022-03-28 17:50:40 浏览数 (2)

实现org.springframework.beans.factory.aware子接口的Bean类在创建时会在调用该bean的init方法之前调用aware子接口的相应方法,举几个类来说明下:

org.springframework.context.ApplicationContextAware的setApplicationContext方法

org.springframework.beans.factory.BeanFactoryAware的setBeanFactory(BeanFactory beanFactory)方法等

通过实现ApplicationContextAware接口,我们就能获取到当前运行的ApplicationContext对象,通过实现BeanFactoryAware接口就能获取到当前系统使用的BeanFactory对象。

但是aware子接口是怎么被调用的呢?这就需要涉及到bean的创建过程中的一个环节:

1.先看org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory类的方法:

代码语言:javascript复制
@Override
	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

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

2.这里会通过getBeanPostProcessors方法获取该BeanFactory对象具体支持的所有BeanPostProcessor,这里用到了java的多态特性,这里以

org.springframework.beans.factory.support.DefaultListableBeanFactory类为例来讲述该类默认提供的BeanPostProcessors如下(所以由DefaultListableBeanFactory类创建的bean对象都要经历这些BeanPostProcessor的摧残):

[org.springframework.context.support.ApplicationContextAwareProcessor, org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker,

org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor, org.springframework.context.annotation.ConfigurationClassPostProcessor$EnhancedConfigurationBeanPostProcessor,

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor, org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor,

org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor, org.springframework.context.support.ApplicationListenerDetector]

3.接下来以ApplicationContextAwareProcessor类为例来讲述该类的postProcessBeforeInitialization方法:

代码语言:javascript复制
	@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;
	}
代码语言:javascript复制

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);
			}
		}
	}

所以想要获取ApplicationContext对象,可以通过实现ApplicationContextAware接口,并实现setApplicationContext接口来获取。

至于DefaultListableBeanFactory类中的其他的BeanPostProcessor感兴趣的小伙伴可以自行查看

0 人点赞