【问题标题】:Spring 4.1.6 - Load ".properties" and initialize a bean with thatSpring 4.1.6 - 加载“.properties”并用它初始化一个bean
【发布时间】:2015-09-20 14:15:46
【问题描述】:

我是 Spring MVC 的新手,我正在做一些测试。我试图找到有关此问题的一些答案,但其中大多数都引用了 Spring 3.11,而我使用的是最后一个版本:4.1.6。

我想在应用程序启动时加载一个“.properties”文件,并使用其中的信息创建一个 bean 以在应用程序的所有上下文中访问它。

到目前为止,我在 servlet-context.xml

中加载文件
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
  ...
  <context:property-placeholder location="classpath*:resources/Resources.properties" />
</beans:beans>

我认为(不太确定)我在 root-context.xml 中正确声明了 bean:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  <!-- Root Context: defines shared resources visible to all other web components -->
  <bean id="Resources" class="ar.com.violenciaesmentir.blog.resources.ResourcesDB"/>
</beans>

而且我也认为我正确地制作了bean,但我真的不知道注释是否正确:

package ar.com.violenciaesmentir.blog.resources;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class ResourcesDB {
  @Value("DB.NAME")
  private String name;

  @Value("DB.TYPE")
  private String type;

  @Value("DB.USER")
  private String user;

  @Value("DB.PASS")
  private String pass;

  @Value("DB.DRIVER")
  private String driver;

  @Value("DB.URL")
  private String url;

  @Value("DB.MAXACTIVE")
  private String maxActive;

  @Value("DB.MAXIDLE")
  private String maxIdle;

  @Value("DB.MAXWAIT")
  private String maxWait;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getType() {
    return type;
  }

  public void setType(String type) {
    this.type = type;
  }

  public String getUser() {
    return user;
  }

  public void setUser(String user) {
    this.user = user;
  }

  public String getPass() {
    return pass;
  }

  public void setPass(String pass) {
    this.pass = pass;
  }

  public String getDriver() {
    return driver;
  }

  public void setDriver(String driver) {
    this.driver = driver;
  }

  public String getUrl() {
    return url;
  }

  public void setUrl(String url) {
    this.url = url;
  }

  public String getMaxActive() {
    return maxActive;
  }

  public void setMaxActive(String maxActive) {
    this.maxActive = maxActive;
  }

  public String getMaxIdle() {
    return maxIdle;
  }

  public void setMaxIdle(String maxIdle) {
    this.maxIdle = maxIdle;
  }

  public String getMaxWait() {
    return maxWait;
  }

  public void setMaxWait(String maxWait) {
    this.maxWait = maxWait;
  }
}

我的“.properties”文件:

DB.NAME = jdbc/Blog
DB.TYPE = javax.sql.DataSource
DB.USER = blog
DB.PASS = blog
DB.DRIVER = oracle.jdbc.driver.OracleDriver
DB.URL = jdbc:oracle:thin:@localhost:1521:xe
DB.MAXACTIVE = 20
DB.MAXIDLE = 5
DB.MAXWAIT = 10000

我认为引用是可以的,因为它在启动服务器时给我带来了麻烦,说它找不到“name”的属性,但是我做错了注释,然后我修复了。

我想要的是初始化该 bean 并可以在 DB 类中拥有一个属性,例如:

@ManagedAttribute
private ResourcesDB resources;
...
public void foo() {
  String dbName = resources.getName();
}

当我尝试时,resources 为空。我做错了什么?

-----更新-----
好的,我可以通过给出的答案进行一些尝试和失败来解决问题。首先,我更正了 ("${DB.NAME}") 之类的 @Value,并在服务注解 @Service(value= “资源”)

然后,我要做的唯一更改是在 servlet-context.xml 中。而不是:

<context:property-placeholder location="classpath*:resources/Resources.properties" />

我用过:

<beans:bean id="configuracion" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <beans:property name="location" value="classpath:Resources.properties"/>
</beans:bean>

并使用 @Autowire 而不是 @ManagedBean 来访问 bean。

【问题讨论】:

  • 寻找PropertyPlaceholderConfigurer,你应该使用"${db.user}"
  • 你应该看看 Spring Boot 和 @ConfigurationProperties

标签: java spring managed-bean properties-file


【解决方案1】:

您的代码中有两处缺陷。

  1. 您的@Value 表达式错误
  2. 您的 &lt;context:property-placeholder /&gt; 必须与 bean 处于相同的上下文中

当使用@Value 时,您必须使用占位符,默认情况下${property name} 您只是使用名称。因此,更新您的注释以反映这一点。 IE。 @Value("${DB.NAME}.

接下来,您在DispatcherServlet 加载的上下文中定义了&lt;context:property-placeholder /&gt;,而您的bean 由ContextLoaderListener 加载。属性占位符 bean 是 BeanFactoryPostProcessor,它只会对加载在相同上下文中的 bean 定义进行操作。基本上,您的 bean 定义在父上下文中,而您的占位符在子上下文中。

修复将 &lt;context:property-placeholder /&gt; 移动到定义 bean 的同一上下文。

使用@Autowired@Inject 代替作为JSF 注释的@ManagedAttribute。如果您没有&lt;context:component-scan /&gt;,请添加&lt;context:annotation-driven /&gt;

【讨论】:

  • 抱歉,回答这么多,我在工作。我按照你说的做了,我在 servlet-context.xml 中定义了 bean:&lt;beans:bean id="Resources" class="ar.com.violenciaesmentir.blog.resources.ResourcesDB"/&gt;&lt;context:component-scan base-package="ar.com.violenciaesmentir" /&gt;´` 并写出像 ("${DB.NAME}") 这样的值,我有这个例外:nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'DB.NAME' in string value "${DB.NAME}"
【解决方案2】:

您的@Value 语法不正确。应该是@Value("${DB.NAME}")

您可能还需要将其添加到您的 XML 配置中:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:resources/Resources.properties" />
</bean> 

位置上的价值可能会有所不同,不确定您是如何构建和构建工件的。

【讨论】:

  • 我在第一时间尝试过,但没有成功。无论如何,我会再试一次,但是当我这样做时:@ManagedAttribute private ResourcesDB resource;给我编译错误:此位置不允许注释“@ManagedAttribute”
  • 嗯,我认为这肯定是问题所在。更新了答案。
  • 你的bean定义和&lt;context:property-placeholder /&gt;一样。
  • 我用解决方案更新了问题,部分原因是这样,非常感谢。只是一件事,似乎在 Spring 4.1.6 中,bean 的定义是“”。再次感谢您。
  • @AndrésMarotta 不,这不取决于您作为根命名空间添加的内容,如果那是 spring-beans.xsd 的其他内容,那么您需要为 bean 元素添加前缀(以及来自xsd) 与您选择的命名空间。这与 spring 无关,而只是 xml 的工作原理。
猜你喜欢
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多