Spring @Value取值为null或@Autowired注入失败

@Value 用于注入.properties文件中定义的内容

@Autowired 用于装配bean

用法都很简单,很直接,但是稍不注意就会出错。下面就来说说我遇到的问题。

 

前两天在项目中遇到了一个问题,大致描述就是我写了如下一个类(只列出关键代码):

复制代码
@Component
@PropertySource("classpath:/config/config.properties")
public class MqttServiceClient implements IMqttServiceClient{
    @Value("${mqtt_host}")
    private String host;
    @Value("${mqtt_client}")
    private String client;

    private MqttClient mqttClient;

    public MqttService(){
    mqttClient= new MqttClient(host,client, new MemoryPersistence()); 
}
}
复制代码

并在其它类中定义了MqttServiceClient 类型的成员变量mqttServiceClient ,并用@Autowired注解进行注入,如下:

public class A{
    @Autowired
    private MqttServiceClient  mqttServiceClient ;  

    ...
}

 

然后运行时发现host和client总是为null,就是没有注入。但是各个配置都是对的,在项目中的其它类用同样的方法使用@Value注解时,就能够取到值。

提示的报错信息是MqttServiceClient 这个bean不能正确的创建。

    一开始我以为是因为@Value注解没有正确取值导致MqttServiceClient 类的构造函数不能正常运行从而导致的错误,所以没在意提示的错误。

后来才发现,我所有的用法都没错,错就错在我重写的构造函数上:

    因为Java类会先执行构造方法,然后再给注解了@Value的成员变量注入值(@Autowired也一样),所以在执行构造方法的时候,就会报错。

我的解决办法是,把@Value注解的属性写入一个AppConfig类中,然后在MqttServiceClient 中注入AppConfig类的对象,并用构造器注入,这样可以明确成员变量的加载顺序。

如下:

复制代码
public class MqttServiceClient implements IMqttServiceClient{

    private AppConfig appConfig;
    private MqttClient mqttClient;

    @Autowired
    public MqttServiceClient(AppConfig appConfig){
        this.appConfig = appConfig;
        mqttClient = new MqttClient (appConfig.getHost(), appconfig.getClient, new MemoryPersistence()
}
}
复制代码
posted @ 2018-06-22 13:54  Max-Jiang  阅读(3030)  评论(0编辑  收藏  举报