@PostConstruct注解的使用,向靜態(tài)變量注入值
今天在編寫工具類時遇到了一個問題,一般在定義工具類方時,我們會將工具類中的方法定義成static類型,使用時可以通過類名.方法名獲取該方法,無需實例化出對象才能使用其內(nèi)部方法,但是當(dāng)有些參數(shù)在配置文件中定義時,我們需要拿到這些參數(shù)就需要在工具類方法使用@Value注解進行參數(shù)注入,但是@Value并不支持向static變量進行注入(spring并不推薦將變量或?qū)ο舐暶鳛閟tatic類型,因為這樣擴大了他們的使用范圍,spring依賴注入的目的就是,需要對象時進行向容器中注入,在整個聲明周期中使用到他們,同時也讓testing工作更加容易,一但聲明為static后,就不需要再產(chǎn)生該對象的實例,這會讓testing變得更加困難,同時你也不能為一個給定的類,依靠注入方式去產(chǎn)生多個具有不同的依賴環(huán)境的實例.
這種static field是隱含共享的,并且是一種global全局狀態(tài),spring同樣不推薦這樣去做.)
因此現(xiàn)在工具類中的參數(shù)如何進行使用,現(xiàn)在注入的參數(shù)是非靜態(tài)的,而方法是靜態(tài)的,如何在靜態(tài)方法中使用到非靜態(tài)變量呢?
可以使用@PostConstruct注解進行使用
說說思路
我們可以通過非靜態(tài)變量進行注入值,再通過@PostConstruct定義的init方法進行將非靜態(tài)的變量值賦給靜態(tài)變量值(這里需要了解下類加載的先后順序)
代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
@Component public class BaiduTranslateUtils { private static Logger logger = LoggerFactory.getLogger(BaiduTranslateUtils. class ); private static String BAIDU_FROM = "en" ; private static String BAIDU_TO = "zh" ; private static String BAIDU_DST = "dst" ; private static String APP_ID; private static String SECURITY_KEY; @Value ( "${baidu.translate.app_id}" ) private String app_id; @Value ( "${baidu.translate.security_key}" ) private String security_key; @PostConstruct public void init(){ //初始化賦值 APP_ID = app_id; SECURITY_KEY = security_key; } public static String getEntozhOfString(String dis){ //靜態(tài)方法使用靜態(tài)變量 System.out.println(APP_ID+SECURITY_KEY); } } |
@PostConstruct和靜態(tài)變量注入和spring初始化
@PostConstruct這個注解是由Java提供的,而不是spring提供的,它用來修飾一個非靜態(tài)的void方法。它會在服務(wù)器加載Servlet的時候運行,并且只運行一次。bean創(chuàng)建完成空對象,就開始進行@Autowire、@PostConstruct賦值。
1
2
3
4
5
6
7
8
9
10
11
|
@Component public class SystemConstant { public static String surroundings; @Value ( "${spring.profiles.active}" ) public String environment; @PostConstruct public void initialize() { System.out.println( "初始化環(huán)境..." ); surroundings = this .environment; } } |
執(zhí)行順序
- 第一種:當(dāng)直接調(diào)用(沒有new對象)靜態(tài)方法時候:代碼塊(靜態(tài)變量按照順序)就執(zhí)行—–方法執(zhí)行。
- 第二種創(chuàng)建對象:執(zhí)行父類靜態(tài)代碼—-執(zhí)行子類的靜態(tài)代碼—-執(zhí)行父類構(gòu)造方法—–執(zhí)行子類的構(gòu)造方法(注:@PostConstruct修飾的方法是在構(gòu)造方法之后執(zhí)行的)
注:靜態(tài)變量和靜態(tài)代碼塊都是按照代碼書寫順序執(zhí)行的,對于靜態(tài)代碼塊只要是操作(調(diào)用靜態(tài)方法或者新建一個類等)這個類就會執(zhí)行(包括靜態(tài)變量)
靜態(tài)變量也可以用value注解進行注入,只要將注解放在變量的set方法上即可,且方法不可為靜態(tài)方法
1
2
3
4
5
6
7
8
9
10
11
|
@Component public class SystemConstant { public static String surroundings; @Value ( "${spring.profiles.active}" ) public String environment; @Value ( "${spring.profiles.active}" ) public void setSurroundings(String surroundings ){ SystemConstant .surroundings = surroundings; } } |
關(guān)于spring初始化操作
實現(xiàn)ApplicationRunner接口,然后Override這個ApplicationRunner接口的run方法即可
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/Ru_yin_hai/article/details/104903046