对于Spring Boot + Integration应用程序,我正在尝试从数据库中加载配置,允许Spring的Environment&通过@Value注解可访问它,并且可以被外部配置覆盖,如Spring Boot参考文档“ 外部化配置”中所述章节。
Environment
@Value
我遇到的问题是我的Spring Integration XML包含${input}无法解决的属性占位符,因为 在 Spring尝试加载XML配置 之前 ,我无法加载数据库支持的配置。
${input}
应用程序的入口点:
@SpringBootApplication public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } }
如何加载数据库配置:
@Configuration public class DbPropertiesConfig { @Autowired private org.springframework.core.env.Environment env; @PostConstruct public void initializeDatabasePropertySourceUsage() { MutablePropertySources propertySources = ((ConfigurableEnvironment) env).getPropertySources(); try { // The below code will be replace w/ code to load config from DB Map<String,Object> map = new HashMap<>(); map.put("input-dir","target/input"); map.put("output-dir","target/output"); DbPropertySource dbPropertySource = new DbPropertySource("si",map); propertySources.addLast(dbPropertySource); } catch (Exception e) { throw new RuntimeException(e); } } }
Spring Integration配置如何加载:
@Profile("IN") @Configuration @ImportResource({"si-common-context.xml","si-input-context.xml"}) public class SiInputAppConfig { }
Spring Integration XML配置si-input-context.xml:
si-input-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/integration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:int-file="http://www.springframework.org/schema/integration/file" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd" default-lazy-init="true"> <int-file:inbound-channel-adapter channel="input2" directory="${input-dir}" filename-pattern="*"> <int:poller fixed-rate="500"/> </int-file:inbound-channel-adapter> <int:service-activator input-channel="input2" ref="sampleEndpoint" method="hello" output-channel="output2"/> <int:channel id="output2"/> <int-file:outbound-channel-adapter channel="output2" directory="${output-dir}"/> </beans:beans>
我得到的错误:
2015-10-28 17:22:18.283 INFO 3816 --- [ main] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [si-common-context.xml] 2015-10-28 17:22:18.383 INFO 3816 --- [ main] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [si-mail-in-context.xml] 2015-10-28 17:22:18.466 INFO 3816 --- [ main] o.s.b.f.config.PropertiesFactoryBean : Loading properties file from URL [jar:file:/C:/Users/xxx/.m2/repository/org/springframework/integration/spring-integration-core/4.1.6.RELEASE/spring-integration-core-4.1.6.RELEASE.jar!/META-INF/spring.integration.default.properties] 2015-10-28 17:22:18.471 INFO 3816 --- [ main] o.s.i.config.IntegrationRegistrar : No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created. 2015-10-28 17:22:18.604 INFO 3816 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; ... 2015-10-28 17:22:18.930 WARN 3816 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean#0.source' defined in null: Could not resolve placeholder 'si.in-input' in string value "${si.in-input}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'input-dir' in string value "${input-dir}" ...
尝试加载XML配置DbPropertiesConfig 后 ,将加载Spring 。
DbPropertiesConfig
我该如何解决这个问题?
提前致谢
美联社
是的,我可以通过家庭测试确认在注解内容之前已加载XML定义。确定其原因已经足够复杂,但是我敢肯定,从本质上讲,@Import*资源比内部@Configuration逻辑更重要。
@Import*
@Configuration
因此,您@PostConstruct不适合与XML混合使用。
@PostConstruct
一种解决方案是将所有Spring Integration配置移至Annotation样式,甚至考虑使用Spring Integration Java DSL。
另一个解决方案是遵循Spring Boot的Externalized Configuration建议:
默认属性(使用指定SpringApplication.setDefaultProperties)。
SpringApplication.setDefaultProperties
这意味着您必须在启动Spring Application之前从数据库中读取属性。是的,如果您打算DataSource在同一应用程序中使用此问题,则将不可能。从另一面来看,让我们再看一次您的目标!您将作为外部配置从数据库加载应用程序的属性,那么从应用程序本身进行加载有什么意义呢?当然,在应用程序启动之前加载和馈送属性会更安全。
DataSource
希望我清楚。