@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{@Autowiredprivate 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;@Autowiredpublic MqttServiceClient(AppConfig appConfig){this.appConfig = appConfig;mqttClient = new MqttClient (appConfig.getHost(), appconfig.getClient, new MemoryPersistence()
}
}