Spring高級接口Aware淺析
Aware 接口功能闡述
Aware 接口提供了一種【內(nèi)置】 的注入手段,例如
a.BeanNameAware 注入 bean 的名字
b.BeanFactoryAware 注入 BeanFactory 容器
c.ApplicationContextAware 注入 ApplicationContext 容器
d.EmbeddedValueResolverAware 注入 ${} 解析器
功能案例演示
public class MyBean implements BeanNameAware, ApplicationContextAware, InitializingBean {
private static final Logger log = LoggerFactory.getLogger(MyBean.class);
@Override
public void setBeanName(String name) {
log.debug("當(dāng)前bean " + this + " 名字叫:" + name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
log.debug("當(dāng)前bean " + this + " 容器是:" + applicationContext);
}
@Override
public void afterPropertiesSet() throws Exception {
log.debug("當(dāng)前bean " + this + " 初始化");
}
@Autowired
public void aaa(ApplicationContext applicationContext) {
log.debug("當(dāng)前bean " + this + " 使用@Autowired 容器是:" + applicationContext);
}
@PostConstruct
public void init() {
log.debug("當(dāng)前bean " + this + " 使用@PostConstruct 初始化");
}
}測試:
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("myBean", MyBean.class);
context.refresh();
context.close();可能這里有人會有疑問: b、c、d 的功能用 @Autowired 就能實(shí)現(xiàn)啊, 為啥還要用 Aware 接口呢
簡單地說:
a.@Autowired 的解析需要用到 bean 后處理器, 屬于擴(kuò)展功能
b.而 Aware 接口屬于內(nèi)置功能, 不加任何擴(kuò)展, Spring 就能識別
某些情況下, 擴(kuò)展功能會失效, 而內(nèi)置功能不會失效
如下所示:
@Autowired
public void aaa(ApplicationContext applicationContext) {
log.debug("當(dāng)前bean " + this + " 使用@Autowired 容器是:" + applicationContext);
}
@PostConstruct
public void init() {
log.debug("當(dāng)前bean " + this + " 使用@PostConstruct 初始化");
}在這里,你會發(fā)現(xiàn)用 Aware 注入 ApplicationContext 成功, 而 @Autowired 注入 ApplicationContext 失敗
擴(kuò)展功能失效場景分析
@Configuration
public class MyConfig1 {
private static final Logger log = LoggerFactory.getLogger(MyConfig1.class);
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
log.debug("注入 ApplicationContext");
}
@PostConstruct
public void init() {
log.debug("初始化");
}
@Bean // beanFactory 后處理器
public BeanFactoryPostProcessor processor1() {
return beanFactory -> {
log.debug("執(zhí)行 processor1");
};
}
}context.refresh();
這行代碼的執(zhí)行順序,到容器里找到所有的.beanFactory 后處理器來執(zhí)行,添加 bean 后處理器,初始化單例。
Java 配置類不包含 BeanFactoryPostProcessor 的情況

Java 配置類包含 BeanFactoryPostProcessor 的情況,因此要創(chuàng)建其中的 BeanFactoryPostProcessor 必須提前創(chuàng)建 Java 配置類,而此時的 BeanPostProcessor 還未準(zhǔn)備好,導(dǎo)致 @Autowired 等注解失效

對應(yīng)代碼
@Configuration
public class MyConfig1 {
private static final Logger log = LoggerFactory.getLogger(MyConfig1.class);
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
log.debug("注入 ApplicationContext");
}
@PostConstruct
public void init() {
log.debug("初始化");
}
@Bean // ?? 注釋或添加 beanFactory 后處理器對應(yīng)上方兩種情況
public BeanFactoryPostProcessor processor1() {
return beanFactory -> {
log.debug("執(zhí)行 processor1");
};
}
}注意
解決方法:
- 用內(nèi)置依賴注入和初始化取代擴(kuò)展依賴注入和初始化
- 用靜態(tài)工廠方法代替實(shí)例工廠方法,避免工廠對象提前被創(chuàng)建
測試:
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("myConfig2", MyConfig2.class);
context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
context.registerBean(CommonAnnotationBeanPostProcessor.class);
context.registerBean(ConfigurationClassPostProcessor.class);
context.refresh();
context.close();輸出結(jié)果:

總結(jié)
- Aware 接口提供了一種【內(nèi)置】 的注入手段, 可以注入 BeanFactory, ApplicationContext
- InitializingBean 接口提供了一種【內(nèi)置】的初始化手段
- 內(nèi)置的注入和初始化不受擴(kuò)展功能的影響, 總會被執(zhí)行, 因此 Spring 框架內(nèi)部的類常用它們
到此這篇關(guān)于Spring高級接口Aware淺析的文章就介紹到這了,更多相關(guān)Spring Aware內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決MyBatis返回結(jié)果類型為Boolean的問題
這篇文章主要介紹了解決MyBatis返回結(jié)果類型為Boolean的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
Springboot2.0自適應(yīng)效果錯誤響應(yīng)過程解析
這篇文章主要介紹了Springboot2.0自適應(yīng)效果錯誤響應(yīng)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11
SpringBoot集成screw實(shí)現(xiàn)數(shù)據(jù)庫文檔生成的代碼示例
數(shù)據(jù)庫設(shè)計文檔是項目技術(shù)文檔的重要組成部分,Screw 是一款開源的數(shù)據(jù)庫文檔生成工具,它支持多種數(shù)據(jù)庫類型,并能生成豐富格式的文檔,本文將通過一個實(shí)際的例子,展示如何使用 Spring Boot 集成 Screw 生成數(shù)據(jù)庫設(shè)計文檔2024-07-07
用Java代碼實(shí)現(xiàn)棧數(shù)據(jù)結(jié)構(gòu)的基本方法歸納
這篇文章主要介紹了用Java代碼實(shí)現(xiàn)棧數(shù)據(jù)結(jié)構(gòu)的基本方法歸納,各種算法的實(shí)現(xiàn)也是ACM上經(jīng)常出現(xiàn)的題目,是計算機(jī)學(xué)習(xí)的基本功,需要的朋友可以參考下2015-08-08

