Spring Boot - @Value返回null

时间:2017-08-30 22:11:21

标签: java spring spring-boot

我正在尝试使用@Value注释并从属性文件中自动填充我的变量,但没有运气。值未设置且为空。

taskService.java

@Service
public class TaskService {
    @Value("${a}")
    String aa;

    public final RestTemplate restTemplate;

    public TaskService(RestTemplateBuilder restTemplateBuilder){
        System.out.println("----------xxxxxxxxxxx-------------" +aa);
        this.restTemplate = restTemplateBuilder.build();
    }

    public Task getTask(int taskId) throws TaskDoesNotExistException{
    try {
        return this.restTemplate.getForObject("/tasks/{taskId}", Task.class, 
        taskId);
    } catch (HttpClientErrorException e) {
        if(e.getRawStatusCode() == 404)
            throw new TaskDoesNotExistException("Task not found", e);
    }
    return null;
}
}

eventhandler.java

@Component
@RepositoryEventHandler(Application.class)
public class ApplicationRepositoryEventHandler {

@Autowired
TaskService taskService;

@HandleBeforeCreate
public void handleApplicationCreate(Application application) throws 
TaskDoesNotExistException{
    for (Integer taskId: application.getTasks()){
        taskService.getTask(taskId);
    }
}

}

6 个答案:

答案 0 :(得分:1)

在构造对象后发生场注入 见https://stackoverflow.com/a/6336013/1544715
只需通过构造函数和TMemo注入aa 一般来说,你应该避免进行野外注射,或者至少尝试每个级别只使用一种类型的注射。

答案 1 :(得分:0)

首先检查您的属性文件是否已加载,通常从输出日志开始,您应该看到属性文件的名称。

然后在您的一个配置文件中配置以下bean(如果尚未完成)。这个bean在@Value中解析'$ {}'。

 @Bean
 public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
 return new PropertySourcesPlaceholderConfigurer();
 }

然后使用你正在做的方式,它应该解析该属性。并确保,实际加载了TaskService bean(组件扫描包应该包括这个类)

虽然我通常使用以上方式,但还有另外一种方法,你可能需要检查(只需fyi,上面应该有效)

 @Autowired
 private Environment env

然后在需要的地方使用属性

 env.getRequiredProperty(“some.property”)

答案 2 :(得分:0)

问题往往是构造函数完成后字段注入完成。这意味着您可以在此之后访问@Value注入的值。 如果方法getAA()已添加到TaskService:

public String getAA() {
 return aa;
}

并且调用此方法,aa的值不为null,因为之前执行了构造函数并且@Value("${a}")的字段注入设置了值。

答案 3 :(得分:0)

 public TaskService(@Value("${a}") String aa, RestTemplateBuilder restTemplateBuilder){
        System.out.println("----------xxxxxxxxxxx-------------" +aa);
        this.restTemplate = restTemplateBuilder.build();
    }

答案 4 :(得分:0)

您的代码无法使用,因为Spring需要首先创建类的实例(调用构造函数),然后将值注入字段。

public TaskService(RestTemplateBuilder restTemplateBuilder, ){
        System.out.println("----------xxxxxxxxxxx-------------" +aa); // 1
        this.restTemplate = restTemplateBuilder.build();
    }

1) in this moment there is no way Spring can inject value to the fields

像这样修复它:

@Service
public class TaskService {

    private final String aa;

    private final RestTemplate restTemplate;

    public TaskService(RestTemplateBuilder restTemplateBuilder, @Value("${a}" String aa){
        this.aa = aa;
        System.out.println("----------xxxxxxxxxxx-------------" +this.aa); // 1
        this.restTemplate = restTemplateBuilder.build();
    }

答案 5 :(得分:0)

这是因为您没有定义以aa作为参数的构造函数,该类也没有setter,因此无法注入它。

请阅读https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-setter-injection