1.Aware
?接口的工作原理
Spring 提供了多個?XXXAware
?接口(如?ApplicationEventPublisherAware
、ApplicationContextAware
、BeanFactoryAware
?等),這些接口的核心作用是讓 Bean?在初始化過程中自動獲取特定的依賴。
- 實現?
Aware
?接口的 Bean:當 Spring 容器創建一個實現了?Aware
?接口的 Bean 時,容器會自動調用接口定義的?setXXX
?方法,傳入對應的依賴對象。 - 無需?
@Autowired
:Aware
?接口的注入由 Spring 容器在 Bean 初始化階段自動觸發,不需要顯式使用?@Autowired
?或構造函數注入。
2.Aware
賦值過程演示
以ApplicationEventPublisherAware
?的賦值過程為例,演示Aware賦值過程。
步驟 1:創建UserService的bean
當Spring 容器初始化?UserService
(它實現了?ApplicationEventPublisherAware
)時,檢測到UserService
?實現了?ApplicationEventPublisherAware
?接口,先執行步驟2.
@Service
public class UserService implements ApplicationEventPublisherAware {private ApplicationEventPublisher publisher;@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher publisher) {this.publisher = publisher; // 這里會被 Spring 自動調用}// 其他方法...
}
步驟 2:Spring 容器檢測到?Aware
?接口
Spring容器檢測到?UserService
?實現了?ApplicationEventPublisherAware
?接口,因此會:
- 查找?
ApplicationEventPublisher
?的實現 Bean:Spring 容器會自動將?ApplicationContext
?作為?ApplicationEventPublisher
?的實現(ApplicationContext
?是 Spring 容器的核心接口,它直接實現了?ApplicationEventPublisher
?接口。因此,Spring 容器會將?ApplicationContext
?自身作為?ApplicationEventPublisher
?的實現傳入。)。 - 調用?
setApplicationEventPublisher
?方法:Spring容器自動調用setApplicationEventPublisher方法
將?ApplicationContext
?的實例賦值給?publisher
?變量。
步驟 3:初始化完成,生成bean
最終,publisher
?變量被賦值為?ApplicationContext
?的實例,UserService初始化完成,生成對應的bean
。
總結:
當Spring容器創建UserService這個Bean的時候,它檢查到這個Bean實現了Aware接口,
Spring 容器自動調用?setApplicationEventPublisher
?方法,將?ApplicationContext
?的實例注入到?publisher
?變量中。
在這個過程中,publisher變量的賦值是通過Spring容器在Bean初始化階段自動完成的,不需要開發者手動使用@Autowired或者其他注解。
3.Aware方式?vs?
@Autowired?
兩種注入方式用法
使用Aware方式 和 使用
@Autowired 引入bean的方式效果類似:
@Service
public class UserServiceWithAutowired {private final ApplicationEventPublisher publisher;@Autowiredpublic UserServiceWithAutowired(ApplicationEventPublisher publisher) {this.publisher = publisher;// 驗證 publisher 是 ApplicationContext 的實例System.out.println("UserServiceWithAutowired.publisher class: " + publisher.getClass().getName()); //輸出:UserServiceWithAutowired.publisher class: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext}//其他業務代碼...
}
@Service
public class UserServiceWithAware implements ApplicationEventPublisherAware {private ApplicationEventPublisher publisher;/*** Aware 類會在Spring啟動時自動設置 ApplicationEventPublisher** @param publisher*/@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher publisher) {this.publisher = publisher;System.out.println("UserServiceWithAware.publisher class: " + publisher.getClass().getName());// 輸出:UserServiceWithAware.publisher class: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext}//其他業務代碼...
}
啟動應用后,上面兩段代碼中的publisher均能賦值完成,對應輸出如下:
兩種注入方式對比
方案 1(Aware
?接口)的特點:
- 無需注解:完全依賴接口實現,適合舊版 Spring 或某些特殊場景(如無法修改構造函數的遺留代碼)。
- 自動注入:Spring 容器在初始化 Bean 時自動調用?
setXXX
?方法。 - 靈活性:可以注入多個?
Aware
?接口(例如同時實現?ApplicationContextAware
?和?BeanFactoryAware
)。 - 注意事項:Aware接口的set方法必須嚴格按照命名規范,比如setApplicationEventPublisher,這樣Spring才能正確識別并調用。如果方法名不對,Spring可能無法正確注入。
方案 2(直接注入?ApplicationEventPublisher
)的優勢:
- 更簡潔:通過?
@Autowired
?或構造函數注入,代碼更清晰。 - 符合現代 Spring 風格:推薦在新項目中使用,因為?
Aware
?接口在某些場景下可能顯得冗余。
總結:Aware
?接口適合需要與容器深度集成的場景,通過這種方式,Spring 實現了依賴注入的另一種形式,無需顯式注解,完全依賴接口的約定。但現代開發更推薦直接通過依賴注入(如?@Autowired
)的方式。