Java Spring @Value 注释总是评估为空?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4130486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:55:15  来源:igfitidea点击:

Spring @Value annotation always evaluating as null?

javaspringspring-mvc

提问by Polaris878

So, I have a simple properties file with the following entries:

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

my.value=123
another.value=hello world

This properties file is being loaded using a PropertyPlaceHolderConfigurer, which references the properties file above.

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

I have the following class, for which I'm trying to load these properties in to like so:

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

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

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

    // More below...
}

The problem is that, mValueand mAnotherValueare ALWAYS null... yet in my Controllers, the value is being loaded just fine. What gives?

问题是,mValue并且mAnotherValue始终为空...但在我的控制器中,该值正在加载得很好。是什么赋予了?

采纳答案by skaffman

If instances of Configare being instantiated manually via new, then Spring isn't getting involved, and so the annotations will be ignored.

如果Config通过 手动实例化 的实例new,则不会涉及 Spring,因此注释将被忽略。

If you can't change your code to make Spring instantiate the bean (maybe using a prototype-scoped bean), then the other option is to use Spring's load-time classloader weaving functionality (see docs). This is some low-level AOP which allows you to instantiate objects as you normally would, but Spring will pass them through the application context to get them wired up, configured, initialized, etc.

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

It doesn't work on all platforms, though, so read the above documentation link to see if it'll work for you.

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

回答by Adeel Ansari

As its working with @Controller, it seems you are instantiating Configyourself. Let the Spring instantiate it.

与 一起使用时@Controller,您似乎正在实例化Config自己。让 Spring 实例化它。

回答by kabal

Add <context:spring-configured />to you application context file.

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

Then add the @Configurableannotation to Configclass.

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

回答by Rob

I had similar issues but was a newbie to Spring. I was trying to load properties into an @Service, and tried to use @Value to retrieve the property value with...

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

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

I spend a whole day trying various combinations of annotations, but it always returned null. In the end the answer as always is obvious after the fact.

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

1) make sure Spring is scanning your class for annotations by including the package hierachy In your servlet.xml (it will scan everything below the base value you insert.

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

2) Make sure you are NOT 'new'ing the class that you just told Spring to look at. Instead, you use @Autowire in the @Controller class.

2) 确保你不是“新”你刚刚告诉 Spring 看的课程。相反,您在@Controller 类中使用@Autowire。

Everything in Spring is a Singleton, and what was happening was Spring loaded the values into its Singleton, then I had 'new'ed another instance of the class which did not contain the newly loaded values so it was always null.

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

Instead in the @Controller use...

相反在@Controller 中使用...

@Autowired
private MyService service; 

Debugging... One thing I did to find this was to extend my Service as follows...

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

@Service
public class MyService implements InitializingBean 

Then put in debug statements in...

然后将调试语句放入...

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

Here I could see the value being set on initialization, and later when I printed it in a method it was null, so this was a good clue for me that it was not the same instance.

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

Another clue to this error was that Tomcat complained of Timeouts trying to read from the Socket with Unable to parse HTTPheader... This was because Spring had created an instance of the service and so had I, so my one was doing the real work, and Spring was timing out on its instance.

此错误的另一个线索是 Tomcat 抱怨超时试图从无法解析 HTTPheader 的 Socket 读取...并且 Spring 在其实例上超时。

回答by Keiv

You can also make your properties private, make sure your class is a Spring bean using @Serviceor @Componentannotations so it always gets instantiated and finally add setter methods annotated with @Value. This ensures your properties will be assigned the values specified in your application.properties or yml config files.

你也可以创建你的属性private,确保你的类是一个 Spring bean,使用@Service@Component注释,这样它总是被实例化,最后添加带有注释的 setter 方法@Value。这确保您的属性将被分配在 application.properties 或 yml 配置文件中指定的值。

@Service
public class Config {
    private static String mValue;

    private static String mAnotherValue;

    @Value("${my.value}")    
    public void setmValue(String mValue) {
    this.mValue = mValue;}

    @Value("${another.value}")
    public void setmAnotherValue(String mAnotherValue) {
    this.mAnotherValue = mAnotherValue;}

    //rest of your code...
}

回答by scottysseus

See my answer here.

在这里看到我的答案。

I ran into the same symptoms (@Value-annotated fields being null) but with a different underlying issue:

我遇到了相同的症状( - 带@Value注释的字段是null),但有一个不同的潜在问题:

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

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

Ensure that you are importing the correct @Valueannotation class! Especially with the convenience of IDEs nowadays, this is a VERY easy mistake to make (I am using IntelliJ, and if you auto-import too quickly without reading WHAT you are auto-importing, you might waste a few hours like I did).

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