Spring SpEL访问Configuration-Bean
Spring SpEL access Configuration-Bean
我在一个遗留软件中工作,其中大部分配置是从 application.properties
外部化的,它驻留在一个名为 custom.properties
的文件中,该文件将被读入这样声明的配置 bean 中。
@Configuration
@ConfigurationProperties(locations = "classpath:custom.properties", ignoreUnknownFields = true, prefix = "custom")
public class CustomProperties {
...
}
此应用程序有一些计划任务,这些任务声明在固定的时间间隔和时间运行。 @Scheduled(cron = "0 0 16 * * 3")
到目前为止一切正常。最近有人要求我在可配置的时间进行此 cronjob。所以我在 custom.properties
中添加了另一个 属性,在 CustomProperties
中添加了一个属性(包括 getter 和 setter)。接下来,我将预定注释更改为如下所示。 @Scheduled(cron = "${@customProperties.cronJob1Schedule}")
当我启动应用程序时出现以下异常:
java.lang.IllegalStateException: Encountered invalid @Scheduled method 'cronJob1': Could not resolve placeholder '@customProperties.cronJob1Schedule' in string value "${@bwvProperties.cronJob1Schedule}"
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:406)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:282)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
以前有人遇到过这个问题吗?为什么我无法访问 SpEL 中的配置 bean?
我认为您打错了字,假设您注入的配置属性与此类似:
@Autowired
private CustomProperties bwvProperties
应该是 #{bwvProperties.cronJob1Schedule}
- 删除 @
,将 $
更改为 #
请注意,有两种不同的机制适用于 Spring 处理的字符串值:
属性 分辨率 - ${my.property}
Spring 可以根据需要用配置的 property sources. This proces simply replaces string key with a string value (and runs it through a converter 中的值替换占位符 ${placeholder}
。
Spring 表达式语言评估 - #{spel.expression}
Spring 能够通过 SPeL 解释器 运行 #{}
的内容。这提供了更强大的工具,因为您可以从表达式内部与应用程序代码进行交互,例如通过从你的一个 bean #{@cumstomProperties.cronJob1Schedule}
.
获取 属性
TL;DR
您只需要在注释值中将 ${
切换为 #{
。
我在一个遗留软件中工作,其中大部分配置是从 application.properties
外部化的,它驻留在一个名为 custom.properties
的文件中,该文件将被读入这样声明的配置 bean 中。
@Configuration
@ConfigurationProperties(locations = "classpath:custom.properties", ignoreUnknownFields = true, prefix = "custom")
public class CustomProperties {
...
}
此应用程序有一些计划任务,这些任务声明在固定的时间间隔和时间运行。 @Scheduled(cron = "0 0 16 * * 3")
到目前为止一切正常。最近有人要求我在可配置的时间进行此 cronjob。所以我在 custom.properties
中添加了另一个 属性,在 CustomProperties
中添加了一个属性(包括 getter 和 setter)。接下来,我将预定注释更改为如下所示。 @Scheduled(cron = "${@customProperties.cronJob1Schedule}")
当我启动应用程序时出现以下异常:
java.lang.IllegalStateException: Encountered invalid @Scheduled method 'cronJob1': Could not resolve placeholder '@customProperties.cronJob1Schedule' in string value "${@bwvProperties.cronJob1Schedule}"
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:406)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:282)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
以前有人遇到过这个问题吗?为什么我无法访问 SpEL 中的配置 bean?
我认为您打错了字,假设您注入的配置属性与此类似:
@Autowired
private CustomProperties bwvProperties
应该是 #{bwvProperties.cronJob1Schedule}
- 删除 @
,将 $
更改为 #
请注意,有两种不同的机制适用于 Spring 处理的字符串值:
属性 分辨率 - ${my.property}
Spring 可以根据需要用配置的 property sources. This proces simply replaces string key with a string value (and runs it through a converter 中的值替换占位符 ${placeholder}
。
Spring 表达式语言评估 - #{spel.expression}
Spring 能够通过 SPeL 解释器 运行 #{}
的内容。这提供了更强大的工具,因为您可以从表达式内部与应用程序代码进行交互,例如通过从你的一个 bean #{@cumstomProperties.cronJob1Schedule}
.
TL;DR
您只需要在注释值中将 ${
切换为 #{
。