所以,我有一个简单的属性文件,其中包含以下条目:
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...
}
问题在于,mValue
和mAnotherValue
总是为空...但在我的控制器中,正好加载了值。是什么给了什么?
答案 0 :(得分:30)
如果通过Config
手动实例化new
的实例,则Spring不会参与,因此注释将被忽略。
如果您无法更改代码以使Spring实例化bean(可能使用prototype
- 作用域bean),那么另一个选项是使用Spring的加载时类加载器编织功能(请参阅{{3 }})。这是一些低级AOP,允许您像往常一样实例化对象,但是Spring会将它们传递给应用程序上下文,以便将它们连接起来,配置,初始化等。
但它并不适用于所有平台,请阅读上述文档链接,看看它是否适合您。
答案 1 :(得分:22)
我有类似的问题,但是春天的新手。 我试图将属性加载到@Service,并尝试使用@Value来检索属性值...
@Autowired
public @Value("#{myProperties['myValue']}") String myValue;
我花了一整天时间尝试各种注释组合,但它总是返回null。 最后,答案一如既往地显而易见。
1)确保Spring通过包含层次结构来扫描您的类以进行注释 在您的servlet.xml中(它将扫描您插入的基值以下的所有内容。
2)确保你不是刚刚告诉Spring要看的课程。相反,你在@Controller类中使用@Autowire。
Spring中的所有东西都是Singleton,发生了什么是Spring将值加载到它的Singleton中,然后我'new'ed该类的另一个实例,它不包含新加载的值,所以它总是为null。
而是在@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);
}
在这里我可以看到在初始化时设置的值,后来当我在方法中打印它时它是null,所以这对我来说是一个很好的线索,它不是同一个实例。
这个错误的另一个线索是Tomcat抱怨Timeout试图从Socket中读取无法解析HTTPheader ......这是因为Spring创建了一个服务实例,所以我也是,所以我的那个人正在做真正的工作,Spring正在实施其实例。
答案 2 :(得分:3)
在使用@Controller
时,您似乎自己正在实例化Config
。让Spring实例化它。
答案 3 :(得分:2)
将<context:spring-configured />
添加到您的应用程序上下文文件中。
然后将@Configurable
注释添加到Config
类。
答案 4 :(得分:0)
您还可以创建属性private
,确保您的类是使用@Service
或@Component
注释的Spring bean,因此它总是被实例化,最后添加使用{{注释的setter方法1}}。这可确保为您的属性分配application.properties或cloud yml配置文件中指定的值。
@Value
答案 5 :(得分:0)
查看我的答案here。
我遇到了相同的症状(@Value
带有注释的字段为null
),但是存在不同的潜在问题:
import com.google.api.client.util.Value;
确保您要导入正确的@Value
注释类!尤其是在如今具有IDE便利的情况下,这是一个非常容易犯的错误(我正在使用IntelliJ,并且如果您自动导入速度太快而没有阅读您要自动导入的内容,那么您可能会像我一样浪费几个小时)。