1、前言
在我们开发项目过程中,经常会通过 @Value(“${xxx}”) 注解方式从属性文件中获取配置信息,但是,稍不注意,获取的值就为 null, 下面列举一下这种情况的注意事项。
2、示例场景
从 application.properties 配置文件中获取 netty.port 的值。
netty.port=8888
public class NettyServer{
@Value("${netty.port}")
private Integer nettyPort;
}
3、错误场景
获取到的 nettyPort 值为 null 的情况如下:
3.1 类未交给 Spring管理
public class NettyServer{
@Value("${netty.port}")
private Integer nettyPort;
}
@Value(“${}”) 是 Spring 的 EL 表达式,属于Spring 的一种注入方式, 所以要想Spring 把 netty.port 的值注入给 NettyServer 类的 nettyPort 属性,就必须把 NettyServer 类交给 Spring 管理,这样 Spring 才知道哪里需要它自动注入。 因此解决办法可以在 NettyServer 类上增加 @Component 注解:
@Component
public class NettyServer{
@Value("${netty.port}")
private Integer nettyPort;
}
3.2 类的字段被 static 或者 final 修饰,如下代码:
@Component
public class NettyServer {
@Value("${netty.port}")
private static Integer nettyPort;
}
NettyServer 类的 nettyPort 属性被 static 修饰,导致获取为 null,这是因为静态变量是类的属性,并不属于对象的属性,而 Spring 是基于对象的属性进行依赖注入的。所以用 @Value 注解注入静态变量是失败的。 解决办法是去掉 static 或 final 。
3.3 使用 NettyServer 的地方是 new 出来而不是通过依赖注入的,获取值为null
使用 NettyServer 的地方是 new 出来而不是通过依赖注入的,获取值为 null。如下代码:
@Component
public class NettyServer{
@Value("${netty.port}")
private Integer nettyPort;
public void start() throws Exception {
System.out.println("端口号:" + nettyPort);
}
}
@Component
public class NettyRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
new NettyServer().start();
}
}
这种场景最容易被忽视,正确使用方式如下代码:
@Component
public class NettyServer{
@Value("${netty.port}")
private Integer nettyPort;
public void start() throws Exception {
System.out.println("端口号:" + nettyPort);
}
}
@Component
@AllArgsConstructor
public class NettyRunner implements ApplicationRunner {
NettyServer nettyServer;
@Override
public void run(ApplicationArguments args) throws Exception {
nettyServer.start();
}
}