Spring相关接口之Aware接口
aware的英文意思:意识到,察觉到,发觉,发现。
从英文翻译来看,aware做的事情应该是发现某一个东西。
接着来看Aware接口源码:
/**
* Marker superinterface indicating that a bean is eligible to be
* notified by the Spring container of a particular framework object
* through a callback-style method. Actual method signature is
* determined by individual subinterfaces, but should typically
* consist of just one void-returning method that accepts a single
* argument.
*/
public interface Aware {
}
注释的大致意思是:Aware是一个标记性的超接口(顶级接口),指示了一个Bean有资格通过回调方法的形式获取Spring容器底层组件。实际回调方法被定义在每一个子接口中,而且通常一个子接口只包含一个接口一个参数并且返回值为void的方法。
说白了:只要实现了Aware子接口的Bean都能获取到一个Spring底层组件。
那么Aware都有哪些子接口呢?
Aware子接口:
其中我们可能比较熟悉的有:BeanFactoryAware、EnvironmentAware、ResourceLoaderAware、ImportAware、BeanNameAware、ApplicationContextAware。
接着我们再来看看BeanNameAware接口的源码:
/**
* Interface to be implemented by beans that want to be aware of their
* bean name in a bean factory. Note that it is not usually recommended
* that an object depend on its bean name, as this represents a potentially
* brittle dependence on external configuration, as well as a possibly
* unnecessary dependence on a Spring API.
*/
public interface BeanNameAware extends Aware {
/**
* Set the name of the bean in the bean factory that created this bean.
* <p>Invoked after population of normal bean properties but before an
* init callback such as {@link InitializingBean#afterPropertiesSet()}
* or a custom init-method.
*/
void setBeanName(String name);
}
BeanNameAware子接口的注释大概意思:实现该接口的Bean,可以获取到Bean的名称。
setBeanName方法的作用就是获取BeanName。
同理可得:
-- 实现BeanFactoryAware接口的Bean,可以获取到BeanFactory组件对象。
-- 实现EnvironmentAware接口的Bean,可以获取到Environment组件对象。
归纳可得:
-- 实现XXXAware接口的Bean,那么通过实现的setXXX方法就可以获取到XXX组件对象。
Aware是spring定义的一种标记性接口,仅仅只是代表一种功能,类似的接口还有我们熟悉的java官方的标记性接口Serializable,表示实现该接口的Bean表可以被序列化到本地,当然Serializable可不像Aware接口那么简单,底层还是有很高深的东西在的,有兴趣研究底层实现的小伙伴,可以参考:https://juejin.im/post/5d0c4bebf265da1bc23f7f1d
此外,Aware接口的使用在Spring实现AOP也有体现。
虽然通过以上的分析可以顺理成章的整理出Aware接口的作用,但是毛主席说过:实践是检验真理的唯一标准,所以上代码检验!!!
--基础环境的准备:导入spring的核心jar包(bean、core、context、expression)
建议通过Maven仓库引入jar包的坐标,只需引入context即可依赖导入另外三个,非常方便。
--编写业务层组件ComponentServiceImpl,并实现BeanFactory接口。
@Service
public class ComponentServiceImpl implements BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public void showBeanFactory() {
System.out.println(beanFactory);
}
}
--编写Spring配置类
@Configuration
@ComponentScan("org.cjw")
public class JavaConfig {
}
--单元测试
@Test
public void testShowBeanFactory() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
ComponentServiceImpl componentServiceImpl = (ComponentServiceImpl) context.getBean("componentServiceImpl");
componentServiceImpl.showBeanFactory();
}
--测试结果
通过结果,可以再得出一个结论,我们真的只需实现XXXAware接口,在实现的setXXX方法中将组件信息保存起来,我们在其他的方法中就可以使用该信息了,支撑这一过程的是后置处理器BeanPostProcessor,BeanPostProcessor作用是在Bean的初始化方法执行前后做事情,
而初始化方法是在Bean创建之后,IOC容器创建完毕之前执行了,所以将setXXX方法通过后置处理器放置在初始化方法之前或者之后执行,那么用户获取到Bean之前就把组件信息保存到Bean中了,所以上诉哪个案例才能打印出BeanFactory对象。
PS:学过反射配合注解就可以模拟spring实现这一过程了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构