Spring表达式语言中使用配置属性时Bean找不到异常的解决方法
异常原因:你在@Scheduled的SpEL表达式中使用#{@jobProperties.getKafkaSendingPeriod()}尝试引用名为jobProperties的Bean,但当前Spring容器中并没有这个名称的Bean——虽然@EnableConfigurationProperties(JobProperties.class)会将JobProperties注册为Bean,但它的默认Bean名称不是jobProperties,而是基于全限定类名生成的内部名称,因此找不到。
以下是几种可行的修复方式:
修复方式一:直接引用当前Bean的注入字段
Job类中已经注入了jobProperties字段,在@Scheduled的SpEL上下文中可以直接访问该字段,无需引用容器中的Bean。修改@Scheduled注解即可:
@Scheduled(fixedRateString="#{jobProperties.kafkaSendingPeriod}")
这种方式无需修改JobProperties类,直接利用已注入的字段取值。
修复方式二:给JobProperties添加@Component注解
让Spring将JobProperties作为普通Bean注册到容器,默认Bean名称就是jobProperties(类名首字母小写),原SpEL表达式就能正常找到它。修改JobProperties类:
@Data @Component @ConfigurationProperties("message-starter") public class JobProperties { public Duration kafkaSendingPeriod; public Duration rabbitSendingPeriod; }
此时Job类上的@EnableConfigurationProperties(JobProperties.class)可保留也可去掉(@Component已完成Bean注册)。
修复方式三:显式声明JobProperties的Bean
如果不想给JobProperties添加@Component,可以创建配置类,通过@Bean显式注册JobProperties并指定Bean名称:
@Configuration public class AppConfig { @Bean @ConfigurationProperties("message-starter") public JobProperties jobProperties() { return new JobProperties(); } }
注册完成后,原SpEL表达式的写法即可正常工作,同时Job类上的@EnableConfigurationProperties可以去掉。
内容的提问来源于stack exchange,提问作者Kirill Zhurbin

