为什么 bean 中的环境在集成上下文中看不到来自源的属性?
Why doesn't Environment in bean see properties from source in integration context?
在我的 Spring 集成 webapp 配置中,我添加了一个 属性 占位符:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:ctx="http://www.springframework.org/schema/context"
...
xsi:schemaLocation="http://www.springframework.org/schema/context
...
">
<ctx:component-scan ... />
<ctx:annotation-config />
<mvc:annotation-driven />
<ctx:property-placeholder location="classpath:config.properties" trim-values="true" />
这是文件内容:
apiPath=/requests
我确定此配置有效,因为我已尝试在 http inbound-channel-adapter 中使用该值:
<int-http:inbound-channel-adapter id="/api${apiPath}"
channel="httpRequestsChannel"
path="${apiPath}"
...>
</int-http:inbound-channel-adapter>
如果我更改 属性 值,前端应用程序将无法到达端点。
但是,在上下文中,我有一个这样配置的端点:
<int:header-value-router input-channel="httpRequestsChannel" ... >
<int:mapping value="POST" channel="httpRequestsPostChannel" />
...
</int:header-value-router>
<int:channel id="httpRequestsPostChannel" />
<int:chain input-channel="httpRequestsPostChannel">
<int:transformer method="transform">
<bean class="transformers.RequestToMessageFile" />
</int:transformer>
...
我想在哪里读取 属性 值:
public class RequestToMessageFile {
@Autowired
private Environment env;
// ...
public Message<?> transform(LinkedMultiValueMap<String, Object> multipartRequest) {
System.out.println("Value: " + env.getProperty("apiPath"));
但在控制台上我看到:
Value: null
我应该曾经在 XML 中声明 属性 源,它将成为整个网络应用程序环境的一部分,我错过了什么?我应该在其他地方声明来源吗?
我注意到如果我添加以下注释:
@Configuration
@PropertySource("classpath:config.properties")
public class RequestToMessageFile {
已正确找到 属性,所以我想这只是一个配置问题。
万一重要,这里是配置集成的 web.xml
部分:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/META-INF/spring.integration/context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
更新
部分遵循 我从 XML 文件中删除了 <ctx:property-placeholder>
并添加了以下 bean:
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:config.properties")
public class WebappConfig {
}
现在 bean 和 XML 文件都可以看到属性。
引用 Martin Deinum:
No it isn't a configuration issue that is how it is supposed to work. The doesn't add properties to the environment. Where as the @PropertySource does.
因此您应该从 XML 配置中删除 <ctx:property-placeholder>
。继续使用 @PropertySource("classpath:config.properties")
并添加这个 bean 定义:
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
注意它必须如何 static
不要急切地加载同一个 @Configuration
中的所有其他 bean。
在我的 Spring 集成 webapp 配置中,我添加了一个 属性 占位符:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:ctx="http://www.springframework.org/schema/context"
...
xsi:schemaLocation="http://www.springframework.org/schema/context
...
">
<ctx:component-scan ... />
<ctx:annotation-config />
<mvc:annotation-driven />
<ctx:property-placeholder location="classpath:config.properties" trim-values="true" />
这是文件内容:
apiPath=/requests
我确定此配置有效,因为我已尝试在 http inbound-channel-adapter 中使用该值:
<int-http:inbound-channel-adapter id="/api${apiPath}"
channel="httpRequestsChannel"
path="${apiPath}"
...>
</int-http:inbound-channel-adapter>
如果我更改 属性 值,前端应用程序将无法到达端点。
但是,在上下文中,我有一个这样配置的端点:
<int:header-value-router input-channel="httpRequestsChannel" ... >
<int:mapping value="POST" channel="httpRequestsPostChannel" />
...
</int:header-value-router>
<int:channel id="httpRequestsPostChannel" />
<int:chain input-channel="httpRequestsPostChannel">
<int:transformer method="transform">
<bean class="transformers.RequestToMessageFile" />
</int:transformer>
...
我想在哪里读取 属性 值:
public class RequestToMessageFile {
@Autowired
private Environment env;
// ...
public Message<?> transform(LinkedMultiValueMap<String, Object> multipartRequest) {
System.out.println("Value: " + env.getProperty("apiPath"));
但在控制台上我看到:
Value: null
我应该曾经在 XML 中声明 属性 源,它将成为整个网络应用程序环境的一部分,我错过了什么?我应该在其他地方声明来源吗?
我注意到如果我添加以下注释:
@Configuration
@PropertySource("classpath:config.properties")
public class RequestToMessageFile {
已正确找到 属性,所以我想这只是一个配置问题。
万一重要,这里是配置集成的 web.xml
部分:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/META-INF/spring.integration/context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
更新
部分遵循 <ctx:property-placeholder>
并添加了以下 bean:
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:config.properties")
public class WebappConfig {
}
现在 bean 和 XML 文件都可以看到属性。
引用 Martin Deinum:
No it isn't a configuration issue that is how it is supposed to work. The doesn't add properties to the environment. Where as the @PropertySource does.
因此您应该从 XML 配置中删除 <ctx:property-placeholder>
。继续使用 @PropertySource("classpath:config.properties")
并添加这个 bean 定义:
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
注意它必须如何 static
不要急切地加载同一个 @Configuration
中的所有其他 bean。