使用 Spring 启动 & Spring 与数据库支持的配置集成

Using Spring Boot & Spring Integration with database backed Configuration

对于 spring 引导 + 集成应用程序,我正在尝试从数据库加载配置,允许 Spring 的 Environment 访问它并通过 @Value 注释并且可以被外部化配置覆盖,如 Externalized Configuration Section 下的 spring 引导参考文档中所述。

我遇到的问题是我的 spring 集成 XML 包含无法解析的 ${input} 属性 占位符,因为我无法获取 之前加载数据库支持的配置 Spring 尝试加载 XML 配置。

应用程序的入口点:

@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 集成配置:

 @Profile("IN")
 @Configuration
 @ImportResource({"si-common-context.xml","si-input-context.xml"})
 public class SiInputAppConfig {
 }

Spring集成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}" ...

Spring 加载 DbPropertiesConfig after XML 尝试加载配置。

我该如何解决这个问题?

提前致谢

AP

是的,我可以通过家庭测试确认 XML 定义是在注释内容之前加载的。确定它的原因已经足够复杂了,但我确信 @Import* 资源比内部 @Configuration 逻辑更重要。

因此您的 @PostConstruct 不适合与 XML 混合使用。

一个解决方案是将所有 Spring 集成配置移动到 Annotation 样式,甚至考虑使用 Spring Integration Java DSL.

另一种解决方案是遵循 Spring 引导的外部化配置建议:

  1. Default properties (specified using SpringApplication.setDefaultProperties).

这意味着您必须在启动 Spring 应用程序之前从数据库中读取属性。是的,如果您打算在同一个应用程序的问题上使用 DataSource,这是不可能的。让我们再从另一边看看你的目标!您将从数据库加载应用程序的属性作为外部配置,那么,从应用程序本身执行此操作的意义何在?当然,在应用程序启动之前加载和提供属性会更安全。

希望我清楚。