【问题标题】:Property does not get filled within dependency jar (Spring 3 / XML)属性未在依赖项 jar 中填充(Spring 3 / XML)
【发布时间】:2017-03-01 05:42:26
【问题描述】:

我们有一个 Spring 托管应用程序,它使用另一个 jar 作为依赖项,其中包含一个 Spring 托管服务类,需要使用从属性文件注入的一些值

带有 Spring 上下文设置的主应用程序

public static void main(String[] args) {
  GenericXmlApplicationContext appContext = new GenericXmlApplicationContext("applicationContext.xml");
  SomeClass someClass = (SomeClass) appContext.getBean("someClass");
  someClass.someMethod();
  ...

从依赖jar调用服务的类

public class SomeClass {
  private ServiceFromTheOtherJar serviceFromTheOtherJar;

  public SomeClass(ServiceFromTheOtherJar serviceFromTheOtherJar) {
    this.serviceFromTheOtherJar = serviceFromTheOtherJar;
  }

  public void someMethod() {
    serviceFromTheOtherJar.call();
    ... 

主应用的applicationContext.xml

<bean name="serviceFromTheOtherJar" class="com...ServiceFromTheOtherJar"/>

<bean name="someClass" class="com...SomeClass">
    <constructor-arg ref="serviceFromTheOtherJar"/>
</bean>

依赖jar中的服务类

public class ServiceFromTheOtherJar {

  private String someFieldWeWantToFillFromPropertyFile;

  public void setSomeFieldWeWantToFillFromPropertyFile(String someFieldWeWantToFillFromPropertyFile) {
    this.someFieldWeWantToFillFromPropertyFile = someFieldWeWantToFillFromPropertyFile;
  }

  public void call() {
    //we would like to use the filled someFieldWeWantToFillFromPropertyFile here
    ...

当然,我们在依赖 jar 中有一个 application.properties 文件,其中包含我们想要注入 someFieldWeWantToFillFromPropertyFile 的属性值

现在我们可以将依赖 jar 作为依赖添加到主应用程序;当主应用程序正在执行时,它的 Spring 上下文设置得很好,并且 ServiceFromTheOtherJar.call() 方法被按预期调用;但是 someFieldWeWantToFillFromPropertyFile 并没有从属性文件中得到填充,无论我们到目前为止尝试过什么(例如@PropertySource({"application.properties"})、Environment.getProperty(...) 等)

限制

  • 我们在两个 jar 中都有 Spring 3 版本,由于部署环境的原因,它必须保持不变;所以 Spring 4 解决方案是没有问题的

  • 正如您在上面看到的,主应用程序当前使用 GenericXmlApplicationContext 并且更改似乎表明对应用程序进行了重大重写。因此,例如似乎无法在 ServiceFromTheOtherJar 上使用 @Service 注释,因为它在执行和上下文设置期间导致 BeanCreationException

【问题讨论】:

    标签: java xml spring properties applicationcontext


    【解决方案1】:

    要从属性文件中读取值,您必须将以下 bean 添加到 applicationContext.xml。

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations" value="classpath:application.properties" />
    </bean>
    

    假设 application.properties 文件包含这样的定义

    myValue=Hello World
    

    service-bean 的定义应该像这样扩展

    <bean name="serviceFromTheOtherJar" class="com...ServiceFromTheOtherJar">
        <property name="someFieldWeWantToFillFromPropertyFile" value="${myValue}" />
    </bean>
    

    现在 Spring 会在 classpath 中查找 application.properties-file 并根据 myValue 设置 service bean 的属性。

    【讨论】:

    • 它有效,谢谢。但我想知道从架构/软件原则的角度来看是否也可以?我的意思是主 jar 访问依赖 jar 的属性文件并管理注入;我找到了所有在依赖 jar 中处理的注释解决方案:拥有自己的 Configuration/ComponentScan 文件,并且 Service 类使用 Value 管理注入。不幸的是,我想不出一个可行的 XML 解决方案。例如main jar 可以导入依赖 jar 自己的 XML 上下文,该上下文声明了服务 bean+属性注入,但在执行期间注入不会发生..
    • 可以为服务 bean 和其他 bean 定义上下文,以读取位于依赖项 jar 中的自己的 xml 文件 (service-context.xml) 中的属性。定义主上下文的文件可以包含带有&lt;import resource="classpath:service-context.xml" /&gt; 的其他文件。
    • 是的,这就是我在之前的评论中提到的尝试但由于某种原因无法正常工作的内容。它编译并且上下文构建成功,但是在执行期间没有注入属性值..
    • 您的上下文是否包含org.springframework.beans.factory.config.PropertyPlaceholderConfigurer 类型的bean?如果缺少该值,则不会从属性文件中读取该值。您是否尝试访问正确的属性文件?如果您重命名它以进行快速测试,则应抛出 java.io.FileNotFoundException
    • 很好的提示,谢谢。显然我们错过了依赖 jar 中正确声明的 PropertyPlaceholderConfigurer bean;声明后,问题似乎解决了。
    猜你喜欢
    • 2012-03-17
    • 2017-11-08
    • 1970-01-01
    • 2022-12-22
    • 1970-01-01
    • 2021-01-15
    • 2014-11-19
    • 1970-01-01
    • 2011-07-19
    相关资源
    最近更新 更多