如何讓你的java變得像spring一樣如此絲滑 Aware

如何讓你的java變得像spring一樣如此絲滑 Aware

前言

aware 意思是注入的意思。今天我們來看看兩個重量級的屬性注入類

servlet

web專案初期就是servlet走天下。那麼ServletContext就不得不提了,在web應用中我們熟悉的有Request作用域和Session作用域

request作用域

一次請求的生命週期,由客戶端建立請求開始到服務端對請求作出響應結束,這就是request的生成周期。

request的時效性很短,往往都是對單詞請求的操作。對請求的引數及響應也都是一次性的

session作用域

超出request作用域,session是針對客戶端的,一個客戶端在一定時間內可以看做是一個session物件。期間可以橫跨多個request請求。

session的使用場景往往都是在使用者的登入操作中

ServletContext作用域

而對於ServletContext他的作用域就更高了,他是凌駕於伺服器之上的。或者說他的生命週期是跟隨伺服器的,伺服器啟動是ServletContext開始,伺服器關閉是ServletContext關閉。

對於ServletContext的使用場景其實我們使用頻率還是挺高的。在MVC中我們介面的請求路徑就是儲存在ServletContext中從而實現資料共享的。因為介面一旦設定好之後在程式執行期間是不會有變動的,在執行期間其它地方需要獲取對映資訊透過ServletContext正好。如果是使用Session的話就設計客戶端保持連線等問題了。

對比

Request、Session、ServletContext三者都是透過鍵值對的方式儲存屬性

三者生命週期逐漸擴大

ServletContext可以透過

getInitParameter

獲取內建在程式中的屬性。透過

getAttribute

獲取動態設定的屬性。可以透過

getResource

獲取資原始檔資訊

ServletContext還有一個臨時檔案地方儲存。透過

javax.servlet.context.tempdir

上下文屬性使用

獲取

public interface ZxhtomComponent extends ApplicationContextAware, ServletContextAware複製程式碼

然後ZxhtomComponent就可以呼叫

getServletContext

來獲取ServletContext類進行實際操作了。

spring

有的時候我們在程式執行期間需要在普通類中獲取Spring中的bean , 這個時候我們就無法透過@Autowire等註解實現屬性注入了。而Spring為我們提供了ApplicationContext 可以手動獲取指定的bean 。 但是該屬性是一個介面如果我們想使用就需要實現ApplicationContextAware這個介面。該介面保證了將ApplicationContext屬性注入

public interface ApplicationContextAware extends Aware { void setApplicationContext(ApplicationContext var1) throws BeansException;}複製程式碼

我們實現這個介面,並在子類中新增ApplicationContext屬性

@Component //這裡必須加,因為最終透過BeanPostProcessor實現回撥的。而該類就是在bean初始化前後攔截的public class ApplicationContextUtil implements ApplicationContextAware { public static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { ApplicationContextUtil。applicationContext = applicationContext; } public static ApplicationContext getApplicationContext() { return ApplicationContextUtil。applicationContext; } public static Object getBean(String name) { return getApplicationContext()。getBean(name); } public static T getBean(Class clazz) { return getApplicationContext()。getBean(clazz); } public static T getBean(String name, Class clazz) { return getApplicationContext()。getBean(name, clazz); }}複製程式碼

這樣一個普通類

ApplicationContextUtil

就完成了,我們可以在我們的任何地方透過該類的

getBean

方法獲取到Spring中的bean了。

如何讓你的java變得像spring一樣如此絲滑 Aware

Aware

上面我們從servlet和spring兩個角度出發實現如何獲取對應的上下文類。servlet中是servletContext , spring中的ApplicationContext 。 而他們都是透過Aware結尾類進行屬性注入的。

換句話來說,他們都繼承了

org.springframework.beans.factory.Aware

介面。他們分別是

ApplicationContextAware

ServletContextAware

Aware的坐擁就是將bean注入到普通類中。從而透過上下文進行相關操作。

其它相關Aware

BeanNameAware

獲取該bean在容器中的名稱

BeanFactoryAware

獲取當前的BeanFactory

MessageSourceAware

獲取MessageSource , 國際化相關

ResourceLoaderAware

獲取ResourceLoader

何處注入

springboot中函式入口在AbstractApplicationContext#refresh方法中。該方法我們可以知道有一個prepareBeanFactory

如何讓你的java變得像spring一樣如此絲滑 Aware

然後我們進去會發現最紅會在invokeAwareInterfaces中對下面的Aware進行屬性回撥。

如何讓你的java變得像spring一樣如此絲滑 Aware

連結:https://juejin。cn/post/7020945160280211464