springcloud-@RefreshScope注解

[复制链接]
发表于 2022-9-17 08:37:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
一.问题


  • 注入过后不调用方法获取不到对应的value值
二.演示



  1. @Component
  2. @RefreshScope
  3. public class Val {
  4.     @Value("${schedule.detectAlarmCron}")
  5.     public String detectAlarmCron;
  6. }
复制代码
获取类
  1. @SpringBootTest
  2. public class Case {
  3.     @Autowired
  4.     private Val val3;
  5.     @Test
  6.     public void case2() throws UnsupportedEncodingException, ParseException {
  7.         System.out.println(val3.detectAlarmCron);
  8.     }
复制代码
输出
  1. null
复制代码
三.原因及解决办法

原因

  • 初步猜测原因,在注入bean时未给成员变量赋值,堆内存中的值一直为null(因为注入的对象是代理出来的),当方法栈内存需要值的时候,从远程的配置中心中取(代理),引用地址是个获取途径,以此保证实时性。
  • 初步猜测已经得到了验证,引用自他人博客:点击跳转至该博客
  1. 这个注解的proxyMode默认值是ScopedProxyMode.TARGET_CLASS,这个代理
  2. 模式使用的是CGLIB方式。如果@RefreshScope使用在@Controller(不止这一个)标记的类上就会出现注入null值的问题。@RefreshScope只要是用在其他会被spring使用CGLIB代理的类上就会出问题。原因是@RefreshScope默认使用CGLIB代理,而目标类又是被CGLIB代理过的,这样就被代理了两次,第二次也就是@RefreshScope代理的时候会出现属性丢失的问题。
复制代码
解决

  • 通过get方法取成员变量值
  • @RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表