PropertySourcesPlaceholderConfigurer 未在 SpringBoot 项目中注册环境 [英] PropertySourcesPlaceholderConfigurer not registering with Environment in a SpringBoot Project
问题描述
我正在将一个工作项目从使用 SpringBoot 命令行参数转移到从文件中读取属性.以下是 @Configuration
类的相关部分:
I am moving a working project from using SpringBoot command line arguments to reading properties from a file. Here are the involved portions of the @Configuration
class:
@Configuration
class RemoteCommunication {
@Inject
StandardServletEnvironment env
@Bean
static PropertySourcesPlaceholderConfigurer placeholderConfigurer () {
// VERIFIED this is executing...
PropertySourcesPlaceholderConfigurer target = new PropertySourcesPlaceholderConfigurer()
// VERIFIED this files exists, is readable, is a valid properties file
target.setLocation (new FileSystemResource ('/Users/me/Desktop/mess.properties'))
// A Debugger does NOT show this property source in the inject Environment
target
}
@Bean // There are many of these for different services, only one shown here.
MedicalSorIdService medicalSorIdService () {
serviceInstantiator (MedicalSorIdService_EpicSoap, 'uri.sor.id.lookup.internal')
}
// HELPER METHODS...
private <T> T serviceInstantiator (final Class<T> classToInstantiate, final String propertyKeyPrimary) {
def value = retrieveSpringPropertyFromConfigurationParameter (propertyKeyPrimary)
classToInstantiate.newInstance (value)
}
private def retrieveSpringPropertyFromConfigurationParameter (String propertyKeyPrimary) {
// PROBLEM: the property is not found in the Environment
def value = env.getProperty (propertyKeyPrimary, '')
if (value.isEmpty ()) throw new IllegalStateException ('Missing configuration parameter: ' + ""$propertyKeyPrimary"")
value
}
使用@Value
注入属性确实有效,但是如果可能的话,我宁愿直接使用Environment
.如果设置不在 Environment
中,那么我不确定 @Value
在哪里提取它们...
Using @Value
to inject the properties does work, however I'd rather work with the Environment
directly if at all possible. If the settings are not in the Environment
then I am not exactly sure where @Value
is pulling them from...
env.getProperty()
在我传入指定属性的命令行参数时继续正常工作.
env.getProperty()
continues to work well when I pass in command line arguments specifying the properties though.
欢迎提出任何建议!
推荐答案
这里的问题是 PropertySourcesPlaceholderConfigurer
和 StandardServletEnvironment
或 Environment
之间的区别> 为简单起见.
The issue here is the distinction between PropertySourcesPlaceholderConfigurer
and StandardServletEnvironment
, or Environment
for simplicity.
Environment
是一个对象,它支持整个 ApplicationContext
并且可以解析一堆属性(Environment
接口扩展了 PropertyResolver
).ConfigurableEnvironment
有一个 MutablePropertySources
对象,您可以通过 getPropertySources()
检索该对象.这个 MutablePropertySources
包含一个 PropertySource
对象的 LinkedList
,这些对象被检查以解析请求的属性.
The Environment
is an object that backs the whole ApplicationContext
and can resolve a bunch of properties (the Environment
interface extends PropertyResolver
). A ConfigurableEnvironment
has a MutablePropertySources
object which you can retrieve through getPropertySources()
. This MutablePropertySources
holds a LinkedList
of PropertySource
objects which are checked in order to resolve a requested property.
PropertySourcesPlaceholderConfigurer
是一个具有自己状态的独立对象.它拥有自己的 MutablePropertySources
对象,用于解析属性占位符.PropertySourcesPlaceholderConfigurer
实现了 EnvironmentAware
,所以当 ApplicationContext
得到它时,它会给它它的 Environment
对象.PropertySourcesPlaceholderConfigurer
将这个 Environment
的 MutablePropertySources
添加到它自己的.然后,它还添加您使用 setLocation()
指定的各种 Resource
对象作为附加属性.这些Resource
对象没有添加到Environment
的MutablePropertySources
中,因此不能用于env.getProperty(字符串)
.
PropertySourcesPlaceholderConfigurer
is a separate object with its own state. It holds its own MutablePropertySources
object for resolving property placeholders. PropertySourcesPlaceholderConfigurer
implements EnvironmentAware
so when the ApplicationContext
gets hold of it, it gives it its Environment
object. The PropertySourcesPlaceholderConfigurer
adds this Environment
's MutablePropertySources
to its own. It then also adds the various Resource
objects you specified with setLocation()
as additional properties. These Resource
objects are not added to the Environment
's MutablePropertySources
and therefore aren't available with env.getProperty(String)
.
因此您无法将PropertySourcesPlaceholderConfigurer
加载的属性直接放入Environment
.你可以做的是直接添加到Environment
的MutablePropertySouces
.一种方法是使用
So you cannot get the properties loaded by the PropertySourcesPlaceholderConfigurer
into the Environment
directly. What you can do instead is add directly to the Environment
's MutablePropertySouces
. One way is with
@PostConstruct
public void setup() throws IOException {
Resource resource = new FileSystemResource("spring.properties"); // your file
Properties result = new Properties();
PropertiesLoaderUtils.fillProperties(result, resource);
env.getPropertySources().addLast(new PropertiesPropertySource("custom", result));
}
或者简单地(感谢@M.Deinum)
or simply (thanks @M.Deinum)
@PostConstruct
public void setup() throws IOException {
env.getPropertySources().addLast(new ResourcePropertySource("custom", "file:spring.properties")); // the name 'custom' can come from anywhere
}
请注意,添加一个 @PropertySource
具有相同的效果,即.直接添加到 Environment
,但您是静态而不是动态添加.
Note that adding a @PropertySource
has the same effect, ie. adding directly to the Environment
, but you're doing it statically rather than dynamically.
这篇关于PropertySourcesPlaceholderConfigurer 未在 SpringBoot 项目中注册环境的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!