Spring之ApplicationContextAware
Spring之ApplicationContextAware
内容概要
ApplicationContextAware
接口能够轻松感知并在Spring中获取应用上下文,进而访问容器中的其他Bean和资源,这增强了组件间的解耦,增加了代码的灵活性和可扩展性,是Spring框架中实现高级功能的关键接口之一。
核心概念
ApplicationContextAware
是Spring框架提供的一个特殊的回调接口,用于帮助对象(特别是普通的Java Bean)访问到Spring的应用上下文ApplicationContext
。
当在自己的类中实现ApplicationContextAware
接口时,可以通过Spring提供的回调机制访问到Spring的应用上下文,从而获得Spring IoC容器中的bean实例、配置信息以及进行国际化操作、事件发布等操作。
在ApplicationContextAware
接口中定义了一个setApplicationContext
方法,当类实现了该接口之后,Spring IoC容器会自动调用该方法并将当前的ApplicationContext
注入到所实现的setApplicationContext
方法中,这样就可以在该类中使用Spring的应用上下文了。
在一些开源的Spring工具库中会看到这种技术的使用,因为这些库往往需要与Spring容器交互,比如读取容器的配置,访问其他的bean等等,通过实现ApplicationContextAware
接口就可以非常方便地完成这些工作。
但注意,一般不推荐在的业务代码中使用,因为这样会增加代码与Spring的耦合性,违反了“依赖于抽象,而非依赖于具体实现”的面向对象设计原则。业务代码应当尽可能减少对具体框架的依赖,以提高代码的通用性和可移植性。
代码案例
下面是一个简单的代码案例,展示了如何使用ApplicationContextAware
接口来创建一个能够访问Spring应用上下文的类,如下代码:
首先,创建一个实现ApplicationContextAware
接口的类:
设计到Spring对static属性的注入问题,请见博文:Spring之static属性的自动注入
1 | import org.springframework.beans.BeansException; |
接着,定义一个简单的服务类作为Spring Bean
1 |
|
在客户端代码中,我们可以通过SpringContextUtil
类来获取DemoService
的实例并调用其方法:
1 | public class ApplicationClient { |
以上代码展示了如何通过SpringContextUtil
访问Spring的应用上下文,并获取其中的一个bean(DemoService
)。
ApplicationClient
类是客户端代码的入口点,它初始化了一个AnnotationConfigApplicationContext
,通过它Spring可以创建和管理beans,随后客户端代码使用SpringContextUtil.getBean
静态方法来获取DemoService
的实例,并调用它的sayHello
方法。
技术原理
ApplicationContextAware
接口是Spring框架中用于让Bean感知到Spring应用上下文ApplicationContext
的存在的一个标记接口。
当Spring容器创建一个实现了ApplicationContextAware
接口的Bean时,它会自动调用该Bean的setApplicationContext
方法,并将当前的ApplicationContext
作为参数传入,这使得Bean能够访问到Spring容器的上下文,进而可以获取容器中的其他Bean、资源、配置信息等。
实现原理
- 标记接口:
ApplicationContextAware
接口本身并没有定义任何具体的业务逻辑,它只是一个标记接口,用于告诉Spring容器这个Bean需要特殊处理。 - 容器回调: 当Spring容器初始化一个Bean时,如果这个Bean实现了
ApplicationContextAware
接口,Spring容器会调用该Bean的setApplicationContext
方法,并将当前的ApplicationContext
对象作为参数传入。 - 内部状态保存: 实现
ApplicationContextAware
接口的Bean通常会在其内部保存这个传入的ApplicationContext
引用,以便后续使用。 - 使用上下文: 一旦Bean保存了
ApplicationContext
的引用,它就可以使用这个上下文来访问容器中的其他Bean,或者获取容器的其他服务。
工作机制
- Bean创建: 当Spring容器根据配置信息创建一个Bean实例时,它会检查这个Bean是否实现了任何
Aware
接口(包括ApplicationContextAware
)。 - Aware接口处理: 如果Bean实现了
Aware
接口,Spring容器会调用相应的set*
方法,注入相应的依赖,对于ApplicationContextAware
,容器会调用setApplicationContext
方法。 - 依赖注入: 在调用
setApplicationContext
方法时,Spring容器会将当前的ApplicationContext
对象注入到Bean中,这个注入过程是通过Java反射机制实现的。 - 使用ApplicationContext: 一旦Bean被初始化并注入了
ApplicationContext
,它就可以使用这个上下文来执行各种操作,比如获取其他Bean、访问资源、读取配置等。
总结:
ApplicationContextAware
接口允许开发者在Bean中轻松获取到应用上下文ApplicationContext
,这使得Bean能够灵活地访问Spring容器中的其他Bean和资源,增强了组件间的解耦和可扩展性。但是,过度使用ApplicationContextAware
可能导致代码与Spring容器紧密耦合,降低了代码的可移植性和可测试性。
参考文档:
Spring揭秘:ApplicationContextAware应用场景及实现原理