一.問題
- 注入過后不呼叫方法獲取不到對應的value值
二.演示
@Component
@RefreshScope
public class Val {
@Value("${schedule.detectAlarmCron}")
public String detectAlarmCron;
}
獲取類
@SpringBootTest
public class Case {
@Autowired
private Val val3;
@Test
public void case2() throws UnsupportedEncodingException, ParseException {
System.out.println(val3.detectAlarmCron);
}
輸出
null
三.原因及解決辦法
原因
- 初步猜測原因,在注入bean時未給成員變數賦值,堆記憶體中的值一直為null(因為注入的物件是代理出來的),當方法堆疊記憶體需要值的時候,從遠程的配置中心中取(代理),參考地址是個獲取途徑,以此保證實時性,
- 初步猜測已經得到了驗證,參考自他人博客:點擊跳轉至該博客
這個注解的proxyMode默認值是ScopedProxyMode.TARGET_CLASS,這個代理
模式使用的是CGLIB方式,如果@RefreshScope使用在@Controller(不止這一個)標記的類上就會出現注入null值的問題,@RefreshScope只要是用在其他會被spring使用CGLIB代理的類上就會出問題,原因是@RefreshScope默認使用CGLIB代理,而目標類又是被CGLIB代理過的,這樣就被代理了兩次,第二次也就是@RefreshScope代理的時候會出現屬性丟失的問題,
解決
- 通過get方法取成員變數值
- @RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/505584.html
標籤:其他
