【问题标题】:Spring @Value annotation always evaluating as null?Spring @Value 注释总是评估为空?
【发布时间】:2011-05-07 00:58:06
【问题描述】:

所以,我有一个包含以下条目的简单属性文件:

my.value=123
another.value=hello world

正在使用PropertyPlaceHolderConfigurer 加载此属性文件,它引用了上面的属性文件。

我有以下类,我正在尝试将这些属性加载到其中:

public class Config
{
    @Value("${my.value}")
    private String mValue;

    @Value("${another.value}")
    private String mAnotherValue;

    // More below...
}

问题在于,mValuemAnotherValue 始终为空...但在我的控制器中,该值被加载得很好。什么给了?

【问题讨论】:

  • Config类是否定义为spring bean?
  • 不是吗?我将如何使用注释来做到这一点?
  • 我尝试在课堂上使用“@Component”和“@Controller”,但都没有成功
  • 那么它在Controller 中的工作原理是什么?你的 Controller 有什么不同?
  • 这让我很困惑...... Config 类和所有东西都在同一个包中......唯一的区别是,我的 Controller 可以工作,我实际上有一个请求映射。

标签: java spring spring-mvc


【解决方案1】:

您还可以将属性设置为private,确保您的类是使用@Service@Component 注释的Spring bean,以便它始终被实例化,最后添加使用@Value 注释的setter 方法。这确保您的属性将被分配在您的 application.properties 或 yml 配置文件中指定的值。

@Service
public class Config {
    private static String myProperty;

    private static String myOtherProperty;

    @Value("${my.value}")    
    public void setMyProperty(String myValue) {
    this.myProperty = myValue;}

    @Value("${other.value}")
    public void setMyOtherProperty(String otherValue) {
    this.myOtherProperty = otherValue;}

    //rest of your code...
}

【讨论】:

    【解决方案2】:

    看我的回答here

    我遇到了相同的症状(@Value-annotated 字段为 null),但存在不同的潜在问题:

    import com.google.api.client.util.Value;

    确保您正在导入正确的 @Value 注释类!尤其是如今 IDE 的便利性,这是一个非常容易犯的错误(我正在使用 IntelliJ,如果您自动导入太快而没有阅读您正在自动导入的内容,您可能会像我一样浪费几个小时)。

    【讨论】:

    • 伟大的发现!就我而言,我使用“org.springframework.boot”插件覆盖了常规的 Spring Boot 依赖项
    【解决方案3】:

    我有类似的问题,但我是 Spring 的新手。 我试图将属性加载到@Service 中,并尝试使用@Value 来检索属性值...

    @Autowired
    public @Value("#{myProperties['myValue']}") String myValue;
    

    我花了一整天的时间尝试各种注释组合,但它总是返回 null。 最后,答案总是事后显而易见。

    1) 确保 Spring 通过包含包层次结构来扫描您的类以查找注释 在您的 servlet.xml 中(它将扫描您插入的基本值以下的所有内容。

    2) 确保您没有“新建”您刚刚告诉 Spring 要查看的类。相反,您在 @Controller 类中使用 @Autowire。

    Spring 中的一切都是单例,发生的事情是 Spring 将值加载到其单例中,然后我“新建”了另一个不包含新加载的值的类实例,因此它始终为空。

    而是在@Controller 中使用...

    @Autowired
    private MyService service; 
    

    调试... 我发现这一点所做的一件事是按如下方式扩展我的服务......

    @Service
    public class MyService implements InitializingBean 
    

    然后在...中放入调试语句

    @Override
    public void afterPropertiesSet() throws Exception {
    // TODO Auto-generated method stub
    LOGGER.debug("property myValue:" + myValue);        
    }
    

    在这里我可以看到初始化时设置的值,后来当我在一个方法中打印它时它是空的,所以这对我来说是一个很好的线索,它不是同一个实例。

    此错误的另一个线索是 Tomcat 抱怨超时尝试从无法解析 HTTPheader 的套接字读取...这是因为 Spring 创建了服务实例,我也创建了,所以我的一个正在做实际工作,Spring 在其实例上超时。

    【讨论】:

    • 这里的 myProperties 是什么。你能解释一下吗?
    • 就我而言,它是#2。从声明为new 切换到@Autowired 解决了我的问题。
    【解决方案4】:

    <context:spring-configured /> 添加到您的应用程序上下文文件中。

    然后将@Configurable注解添加到Config类中。

    【讨论】:

      【解决方案5】:

      如果Config 的实例是通过new 手动实例化的,那么Spring 不会参与其中,因此注释将被忽略。

      如果您无法更改代码以使 Spring 实例化 bean(可能使用 prototype-scoped bean),那么另一个选择是使用 Spring 的加载时类加载器编织功能(请参阅 docs)。这是一些低级 AOP,它允许您像往常一样实例化对象,但 Spring 将通过应用程序上下文传递它们以使它们连接、配置、初始化等。

      不过,它并不适用于所有平台,因此请阅读上面的文档链接,看看它是否适合您。

      【讨论】:

      • 嘿 skaffman,感谢您的建议...问题是我正在从 JSP 实例化 Config。我不确定我是否能找到解决方法?也许通过使用某种工厂?
      • @Polaris878:我的建议仍然适用于 JSP 实例化的对象(任何通过反射实例化的对象)
      • +1。我抓紧详细了解Spring。多年没碰过。愚蠢的工作场所。
      • +1 哦,天哪……这救了我!试图读取属性文件,但不确定为什么 @Value 给出 null
      • 我尝试了所有指南,检查了 50 次配置,使用了所有可能的注释.. 几乎发疯了,然后我决定测试控制器是否看到该属性.. 是的!和服务 - 太!在我的情况下,这实际上是用 new 初始化的服务中使用的对象:D
      【解决方案6】:

      由于它与@Controller 一起工作,您似乎正在自己实例化Config。让 Spring 实例化它。

      【讨论】:

      • 啊,是的,这就是问题所在......我自己在调用构造函数。那么,我怎样才能访问这些属性?如果我无法访问这些属性,那基本上意味着我需要找到其他方式来加载配置,因为如果这些属性仅在某些情况下可用,Spring 属性加载器就不会削减它。
      • @Polaris878:让 Spring 实例化它。我们有什么问题吗?或者使用ResourceBundle自己做。
      猜你喜欢
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 2018-03-10
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 2014-05-29
      • 2016-10-03
      相关资源
      最近更新 更多