Spring中Aware的用法以及实现

Aware

在Spring当中有一些内置的对象是未开放给我们使用的,例如Spring的上下文ApplicationContext、环境属性Environment,BeanFactory等等其他的一些内置对象,而在我们可以通过实现对应的Aware接口去拿到我们想要的一些属性,一般命名都是xxxAware,在创建对象的时候, 会调用接口规定的方法注入到相关组件:Aware

常用的Aware:

用法示例:

源码解析

我们先了解什么是BeanPostProcessor,是在创建Bean之前以及创建Bean之后的一种后置处理器,这里就简单的讲一下这个,就是在我们使用的这些注解,例如:@Async (异步执行),@Bean,@Component、@Autowired、@PropertySource等等都需要经过BeanPostProcessor去处理才能加载到容器当中,

先看一个示例:

不仅仅有BeanPostProcessor还有BeanDefinitionRegistryPostProcessor(Bean注册器后置处 理器)、BeanFactoryPostProcessor(BeanFactory后置处理器),

在处理Aware实现类的时候就会有对应的一个AwareProcessor去处理,我们拿ApplicationContextAware做示例**:**

我们找到对应的后置处理器ApplicationContextAwareProcessor

因为BeanPostProcessor有两个接口实现,但是只对处理前做内置对象赋值,将对应的对象暴露给我们

复制代码
class ApplicationContextAwareProcessor implements BeanPostProcessor {

	private final ConfigurableApplicationContext applicationContext;

	private final StringValueResolver embeddedValueResolver;


	/**
	 * Create a new ApplicationContextAwareProcessor for the given context.
	 */
	public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
		this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
	}


	@Override
	@Nullable
	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;
	}

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

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) {
		return bean;
	}

}

不得不说Spring的这种设计还是很厉害的,建议可以买本Spring IOC源码分析的书看看比较好,了解的更加细致

相关推荐
Database_Cool_13 小时前
AI Agent 长期记忆怎么存?阿里云 PolarDB-X 对接 Mem0 记忆框架实践
数据库·阿里云
会编程的土豆13 小时前
数据库范式
数据库·oracle
L16247613 小时前
MySQL 全环境生产快速安装 + 完整配置手册(整合国产银河麒麟适配 + 主从补充版)
数据库·mysql
yio_yin13 小时前
Spring事务管理(数据一致性)
数据库·sql·spring
X Chow13 小时前
MongoDB Beginner Guide 01:理解 NoSQL、文档模型与 Python 开发环境
数据库·mongodb·nosql
前端双越老师14 小时前
如何以前端视角(非0基础)学 Java ?
java·node.js·全栈
前端世界14 小时前
MySQL 基础入门(学习第4天)——约束与 DML 操作详解
数据库·学习·mysql
dear_bi_MyOnly14 小时前
【SpringBoot配置文件】
java·spring boot·后端·学习·spring·java-ee·学习方法
做个文艺程序员14 小时前
Linux第22篇:用Docker容器化你的Java SaaS应用:一次构建,随处运行
java·docker·容器
nianniannnn15 小时前
Qt QMessageBox知识点
开发语言·数据库·qt