新闻详情

新闻详情

首页 / 资讯中心 / 详情

Spring Aware 系列接口详解

发布时间:2026/9/26 7:00:56来源:尧图网络
Spring Aware 系列接口详解
Spring Aware 系列接口详解一、什么是 Aware 接口Aware 是 Spring 提供的一组回调接口。Bean 实现这些接口后Spring 容器会在创建 Bean 的过程中主动调用对应的方法把容器内部的资源“告知”给 Bean。简单说Aware 接口让 Bean 能够感知到自己所处的容器环境从而获取容器的名称、上下文、环境变量等资源。ComponentpublicclassMyBeanimplementsBeanNameAware{OverridepublicvoidsetBeanName(Stringname){// Spring 回调告知 Bean 自己的名称System.out.println(我的 Bean 名称是name);}}二、为什么需要 Aware 接口普通 Bean 不应该感知 Spring 容器的存在这是 Spring 非侵入性设计的一部分。但有些场景下Bean 确实需要获取容器资源需要知道自己的 Bean 名称用于日志、监控需要获取ApplicationContext来动态获取其他 Bean需要读取Environment中的配置需要加载资源文件需要发布事件Aware 接口提供了一种“受控”的方式让 Bean 在需要时能够获取这些资源而不必强制依赖 Spring 容器。三、常用 Aware 接口一览Aware 接口回调方法获取的资源调用者BeanNameAwaresetBeanName(String)Bean 的名称AbstractAutowireCapableBeanFactoryBeanClassLoaderAwaresetBeanClassLoader(ClassLoader)类加载器AbstractAutowireCapableBeanFactoryBeanFactoryAwaresetBeanFactory(BeanFactory)BeanFactory 实例AbstractAutowireCapableBeanFactoryEnvironmentAwaresetEnvironment(Environment)Environment 实例ApplicationContextAwareProcessorEmbeddedValueResolverAwaresetEmbeddedValueResolver(...)占位符解析器ApplicationContextAwareProcessorResourceLoaderAwaresetResourceLoader(ResourceLoader)资源加载器ApplicationContextAwareProcessorApplicationEventPublisherAwaresetApplicationEventPublisher(...)事件发布器ApplicationContextAwareProcessorMessageSourceAwaresetMessageSource(MessageSource)国际化消息源ApplicationContextAwareProcessorApplicationContextAwaresetApplicationContext(ApplicationContext)ApplicationContext 实例ApplicationContextAwareProcessorServletContextAwaresetServletContext(ServletContext)ServletContextServletContextAwareProcessorServletConfigAwaresetServletConfig(ServletConfig)ServletConfigServletContextAwareProcessorLoadTimeWeaverAwaresetLoadTimeWeaver(LoadTimeWeaver)LTW 织入器LoadTimeWeaverAwareProcessor四、三类 Aware 接口的调用时机Aware 接口的调用分布在 Bean 生命周期的不同阶段主要分为三类。1. BeanNameAware、BeanClassLoaderAware、BeanFactoryAware这三个接口由AbstractAutowireCapableBeanFactory.invokeAwareMethods()调用时机在属性赋值之后、初始化之前。privatevoidinvokeAwareMethods(StringbeanName,Objectbean){if(beaninstanceofAware){if(beaninstanceofBeanNameAware){((BeanNameAware)bean).setBeanName(beanName);}if(beaninstanceofBeanClassLoaderAware){ClassLoaderbclgetBeanClassLoader();if(bcl!null){((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);}}if(beaninstanceofBeanFactoryAware){((BeanFactoryAware)bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}调用顺序BeanNameAware→BeanClassLoaderAware→BeanFactoryAware。2. EnvironmentAware、ResourceLoaderAware 等这些接口由ApplicationContextAwareProcessor调用时机在BeanPostProcessor.postProcessBeforeInitialization阶段也就是初始化前。ApplicationContextAwareProcessor是一个BeanPostProcessor它会在初始化前检查 Bean 是否实现了这些 Aware 接口publicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){if(!(beaninstanceofEnvironmentAware||beaninstanceofEmbeddedValueResolverAware||beaninstanceofResourceLoaderAware||beaninstanceofApplicationEventPublisherAware||beaninstanceofMessageSourceAware||beaninstanceofApplicationContextAware)){returnbean;}// 依次调用各个 Aware 接口invokeAwareInterfaces(bean);returnbean;}调用顺序EnvironmentAware→EmbeddedValueResolverAware→ResourceLoaderAware→ApplicationEventPublisherAware→MessageSourceAware→ApplicationContextAware。3. ServletContextAware、ServletConfigAware这两个接口由ServletContextAwareProcessor调用也是BeanPostProcessor在 Web 应用中生效。4. 调用时机总结① 实例化 ② 属性赋值 ③ BeanNameAware → BeanClassLoaderAware → BeanFactoryAware ④ 初始化前 EnvironmentAware → EmbeddedValueResolverAware → ResourceLoaderAware → ApplicationEventPublisherAware → MessageSourceAware → ApplicationContextAware → ServletContextAware → ServletConfigAware ⑤ 初始化 ⑥ 初始化后 ⑦ 销毁五、常用接口详解1. BeanNameAware获取自己在容器中的 Bean 名称。常用于日志、监控、注册中心等场景。ComponentpublicclassMyServiceimplementsBeanNameAware{privateStringbeanName;OverridepublicvoidsetBeanName(Stringname){this.beanNamename;}publicvoiddoSomething(){System.out.println(当前 Bean 名称beanName);}}2. BeanFactoryAware获取BeanFactory实例可以动态获取其他 Bean。但日常开发中更推荐用ApplicationContextAware。ComponentpublicclassMyServiceimplementsBeanFactoryAware{privateBeanFactorybeanFactory;OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory){this.beanFactorybeanFactory;}publicvoiddoSomething(){UserDaouserDaobeanFactory.getBean(UserDao.class);userDao.save();}}3. ApplicationContextAware获取ApplicationContext实例可以获取 Bean、发布事件、获取环境等。这是最常用的 Aware 接口。ComponentpublicclassSpringContextHolderimplementsApplicationContextAware{privatestaticApplicationContextcontext;OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext){SpringContextHolder.contextapplicationContext;}publicstaticTTgetBean(ClassTclazz){returncontext.getBean(clazz);}}4. EnvironmentAware获取Environment实例可以读取配置、判断 Profile。ComponentpublicclassMyServiceimplementsEnvironmentAware{privateEnvironmentenvironment;OverridepublicvoidsetEnvironment(Environmentenvironment){this.environmentenvironment;}publicvoiddoSomething(){Stringportenvironment.getProperty(server.port);if(environment.acceptsProfiles(prod)){// 生产环境逻辑}}}5. ResourceLoaderAware获取ResourceLoader用于加载资源文件。ComponentpublicclassMyServiceimplementsResourceLoaderAware{privateResourceLoaderresourceLoader;OverridepublicvoidsetResourceLoader(ResourceLoaderresourceLoader){this.resourceLoaderresourceLoader;}publicvoidloadFile()throwsIOException{ResourceresourceresourceLoader.getResource(classpath:data.txt);try(InputStreamisresource.getInputStream()){// 读取文件}}}6. ApplicationEventPublisherAware获取事件发布器用于发布应用事件。ComponentpublicclassMyServiceimplementsApplicationEventPublisherAware{privateApplicationEventPublisherpublisher;OverridepublicvoidsetApplicationEventPublisher(ApplicationEventPublisherpublisher){this.publisherpublisher;}publicvoiddoSomething(){publisher.publishEvent(newMyEvent(业务完成));}}7. MessageSourceAware获取国际化消息源用于读取多语言消息。ComponentpublicclassMyServiceimplementsMessageSourceAware{privateMessageSourcemessageSource;OverridepublicvoidsetMessageSource(MessageSourcemessageSource){this.messageSourcemessageSource;}publicStringgetMessage(Stringcode,Localelocale){returnmessageSource.getMessage(code,null,locale);}}六、完整示例ComponentpublicclassAwareBeanimplementsBeanNameAware,BeanFactoryAware,EnvironmentAware,ApplicationContextAware,InitializingBean{publicAwareBean(){System.out.println(1. 构造方法);}OverridepublicvoidsetBeanName(Stringname){System.out.println(3.1 BeanNameAware: name);}OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory){System.out.println(3.2 BeanFactoryAware);}OverridepublicvoidsetEnvironment(Environmentenvironment){System.out.println(4.1 EnvironmentAware);}OverridepublicvoidsetApplicationContext(ApplicationContextcontext){System.out.println(4.2 ApplicationContextAware);}OverridepublicvoidafterPropertiesSet(){System.out.println(5. InitializingBean);}}输出1. 构造方法 属性赋值 3.1 BeanNameAware: awareBean 3.2 BeanFactoryAware 4.1 EnvironmentAware 4.2 ApplicationContextAware 5. InitializingBean七、Aware 接口的底层原理Aware 接口的调用分两个阶段分别由不同的组件负责。1. invokeAwareMethodsAbstractAutowireCapableBeanFactory在initializeBean()方法中调用invokeAwareMethods()处理BeanNameAware、BeanClassLoaderAware、BeanFactoryAware。这三个接口被放在AbstractAutowireCapableBeanFactory中直接调用是因为它们不依赖ApplicationContext只需要BeanFactory层面的信息。2. ApplicationContextAwareProcessorApplicationContextAwareProcessor是一个BeanPostProcessor负责处理更高级的 Aware 接口。它在postProcessBeforeInitialization中检查并调用这些接口。classApplicationContextAwareProcessorimplementsBeanPostProcessor{privatefinalConfigurableApplicationContextapplicationContext;OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){if(beaninstanceofEnvironmentAware){((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());}if(beaninstanceofEmbeddedValueResolverAware){((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(newEmbeddedValueResolver(applicationContext.getBeanFactory()));}if(beaninstanceofResourceLoaderAware){((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);}if(beaninstanceofApplicationEventPublisherAware){((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);}if(beaninstanceofMessageSourceAware){((MessageSourceAware)bean).setMessageSource(this.applicationContext);}if(beaninstanceofApplicationContextAware){((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);}returnbean;}}这个处理器由AbstractApplicationContext.prepareBeanFactory()注册到容器中。3. ServletContextAwareProcessor在 Web 应用中ServletContextAwareProcessor负责处理ServletContextAware和ServletConfigAware同样通过BeanPostProcessor机制实现。八、注意事项1. Aware 接口不是越多越好实现 Aware 接口意味着 Bean 与 Spring 容器产生了耦合。过度使用会让 Bean 难以脱离 Spring 环境使用违背了非侵入性设计原则。只在确实需要时使用。2. 静态字段的坑ApplicationContextAware的setApplicationContext是实例方法不能直接注入静态字段。需要通过实例方法赋值给静态变量ComponentpublicclassSpringContextHolderimplementsApplicationContextAware{privatestaticApplicationContextcontext;OverridepublicvoidsetApplicationContext(ApplicationContextctx){SpringContextHolder.contextctx;// 赋值给静态变量}publicstaticTTgetBean(ClassTclazz){returncontext.getBean(clazz);}}3. 调用顺序同类中多个 Aware 接口的调用顺序是固定的不由接口声明顺序决定。如果需要控制顺序可以在方法中添加日志观察或依赖 Spring 的固定顺序。4. 与 Autowired 的区别Autowired用于注入依赖 Bean而 Aware 接口用于获取容器本身的基础设施。两者用途不同不要混用。九、总结维度核心要点作用让 Bean 感知容器环境获取容器内部资源调用时机属性赋值之后、初始化之前三类接口BeanNameAware等由invokeAwareMethods调用ApplicationContextAware等由ApplicationContextAwareProcessor调用ServletContextAware等由ServletContextAwareProcessor调用常用接口BeanNameAware、BeanFactoryAware、ApplicationContextAware、EnvironmentAware底层实现BeanPostProcessor机制注意事项不要过度使用避免与 Spring 容器耦合过深典型应用获取上下文、读取配置、发布事件、加载资源Aware 接口是 Spring 提供的一种“受控耦合”机制。它让 Bean 在需要时能获取容器资源同时又不强制所有 Bean 都依赖 Spring。理解 Aware 接口的调用时机和底层原理能帮你更好地掌握 Bean 生命周期的细节也能在需要时选择合适的 Aware 接口解决问题。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

从执行代码到临时Runtime:Agent云沙箱架构实战 2026/9/26 18:38:06

从执行代码到临时Runtime:Agent云沙箱架构实战

1. 让 Agent 从“会写代码”到“能管理一个临时Runtime” 1.1 Agent 过去那种“执行代码”方式,到底缺什么 我见过太多 Agent 项目,demo 时一路绿灯,真要让它在业务环境里跑,第一关往往就卡在“代码跑不起来”。一开始大家都觉得…

阅读更多 →
智慧水务Axure高保真原型:解压、交互设计与交付避坑全指南 2026/9/26 18:38:06

智慧水务Axure高保真原型:解压、交互设计与交付避坑全指南

简介:这份zip压缩包是智慧水务云平台的Axure高保真原型,由ilovemockup.club整理,面向产品经理、交互设计师及开发团队,用于直观理解水务管理系统的界面布局、交互流程与功能模块,覆盖物联网监控、大数据分析、人工智能…

阅读更多 →
View UI Table 与 Page 组件分页实战:前端分页与服务端分页完整指南 2026/9/26 18:38:06

View UI Table 与 Page 组件分页实战:前端分页与服务端分页完整指南

1. 分页到底在解决什么问题:先想清楚场景再动手先讲个现象。我见过不少刚接触 View UI(以前叫 iView)的开发者,拿到 Table 和 Page 组件后第一件事就是照着文档抄一遍代码,抄完发现表格能显示数据、页码也能点&#xf…

阅读更多 →
C++算法模板库:从设计到实战的完整指南 2026/9/26 18:38:06

C++算法模板库:从设计到实战的完整指南

简介:这是一份面向竞赛编程与算法学习者的C算法模板库,聚焦在有限时间内快速调用经过优化的常用算法与数据结构,解决大规模数据与高性能计算场景下的实现难题。压缩包共127个文件,以123个cpp源码为主体,另含2个md说明、…

阅读更多 →
YOLOv8推理性能benchmark实战指南:构建可归因的FPS坐标系 2026/9/26 18:38:06

YOLOv8推理性能benchmark实战指南:构建可归因的FPS坐标系

1. 这不是跑个demo就完事的“FPS测试”:YOLOv8推理速度 benchmark 的真实战场你看到过太多标题写着“YOLOv8 FPS实测:RTX3060跑出120帧!”的文章,点进去一看,代码就三行,测试图是单张19201080的空旷街道&am…

阅读更多 →
球球大作战网络卡顿掉线排查实录:从手机到路由器的逐层优化指南 2026/9/26 18:37:59

球球大作战网络卡顿掉线排查实录:从手机到路由器的逐层优化指南

1. 从一次深夜掉线说起:球球大作战网络问题到底难在哪凌晨一点半,决胜局刚吞掉第三个小球,体积冲到全屏第一,屏幕突然卡成幻灯片,紧接着弹出“网络连接中断”——这种体验我相信每个球球老玩家都经历过。更气人的是&am…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉