PropertySourcesPlaceholderConfigurer不在SpringBoot项目中注册到Environment [英] PropertySourcesPlaceholderConfigurer not registering with Environment in a SpringBoot Project
问题描述
我正在将使用SpringBoot命令行参数的工作项目移动到从文件中读取属性。以下是 @Configuration
类的相关部分:
@Configuration
class RemoteCommunication {
@Inject
StandardServletEnvironment env
$ b @Bean
static PropertySourcesPlaceholderConfigurer placeholderConfigurer(){
// VERIFIED this is executed ...
PropertySourcesPlaceholderConfigurer target = new PropertySourcesPlaceholderConfigurer()
// VERIFIED这个文件存在,可读,是一个有效的属性文件
target.setLocation(new FileSystemResource ('/Users/me/Desktop/mess.properties'))
//一个调试器在注入环境中不显示这个属性源
target
}
@Bean //对于不同的服务有很多种,这里只显示一个。
MedicalSorIdService medicalSorIdService(){
serviceInstantiator(MedicalSorIdService_EpicSoap,'uri.sor.id.lookup.internal')
}
//帮助者方法...
私人< T> T serviceInstantiator(final Class< T> classToInstantiate,final String propertyKeyPrimary){
def value = retrieveSpringPropertyFromConfigurationParameter(propertyKeyPrimary)
classToInstantiate.newInstance(value)
}
private def retrieveSpringPropertyFromConfigurationParameter(String propertyKeyPrimary){
// PROBLEM:在环境中找不到该属性
def value = env.getProperty(propertyKeyPrimary,'')
if(value .isEmpty())抛出新的IllegalStateException('Missing配置参数:'+\$ propertyKeyPrimary \)
value
}
使用 @Value
注入属性属性,但是我会而是尽可能直接使用 Environment
>。如果这些设置不在 Environment
中,那么我不太确定 @Value
是从哪里拉出来的......
env.getProperty()
当我传递指定属性的命令行参数时继续工作。
欢迎提供任何建议! 在 PropertySourcesPlaceholderConfigurer
和 StandardServletEnvironment
或 Environment
之间。
$ b
Environment
是一个支持整个 ApplicationContext
并且可以解析一堆属性( Environment interface extends
PropertyResolver
)。一个 ConfigurableEnvironment
有一个 MutablePropertySources
对象,您可以通过 getPropertySources()
。这 MutablePropertySources
包含 PropertySource
被检查对象的 LinkedList
以解析所请求的属性。
PropertySourcesPlaceholderConfigurer
是一个独立的对象,具有自己的状态。它拥有自己的 MutablePropertySources
对象来解析属性占位符。 PropertySourcesPlaceholderConfigurer
implements EnvironmentAware
所以当 ApplicationContext
得到它时,它给它它的 Environment
对象。 PropertySourcesPlaceholderConfigurer
将此 Environment MutablePropertySources
添加到它自己的。然后它还会将您用 setLocation()
指定的各种对象添加为其他属性。 这些
资源
对象不会被添加到 Environment 的
MutablePropertySources
,因此不可用于 env.getProperty(String)
。
因此,您无法直接将 PropertySourcesPlaceholderConfigurer
加载的属性放入 Environment
中。你可以直接添加到 Environment
的 MutablePropertySouces
中。一种方法是使用
@PostConstruct
public void setup()throws IOException {
Resource resource = new的FileSystemResource( spring.properties); //你的文件
属性result = new Properties();
PropertiesLoaderUtils.fillProperties(result,resource);
env.getPropertySources()。addLast(new PropertiesPropertySource(custom,result));
$ / code>
或简单地(谢谢@ M.Deinum)
@PostConstruct $ b $ public void set()throws IOException {
env.getPropertySources()。addLast(new ResourcePropertySource(custom, 文件:spring.properties)); //名称'custom'可以来自任何地方
}
请注意, code> @PropertySource 具有相同的效果,即。直接添加到 Environment
中,但是您正在静态而不是动态地添加。
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
}
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()
continues to work well when I pass in command line arguments specifying the properties though.
Any suggestions are welcome!
The issue here is the distinction between PropertySourcesPlaceholderConfigurer
and StandardServletEnvironment
, or Environment
for simplicity.
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
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)
.
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));
}
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
}
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项目中注册到Environment的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!