无法将 属性 值注入 class 参数(@Value 注释)
Cannot inject property value to class parameter (@Value annotatnion)
我正在学习 Spring Boot,我的问题可能很简单,但对我来说还不够清楚。我在使用 @Value 注释时遇到了一些问题 - 我想知道为什么应用程序 属性 不能注入到 class 参数。
我使用 Spring Initializr 准备了一些非常基本的项目,并向我的 "application.properties" 资源添加了一个 属性。此外,我创建了两个额外的 classes:"YellowCar"(工作正常)和 "RedCar"(不起作用 - 无法正确注入参数)。
"application.properties" 文件:
car.age=15
我申请的主要class:
package com.example.helper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;
@SpringBootApplication
public class HelperApplication implements CommandLineRunner {
@Autowired
private Environment env;
public static void main(String[] args) {
SpringApplication.run(HelperApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println (new RedCar(env));
System.out.println (new YellowCar());
}
}
RedCar 是通过将环境变量传递给构造函数来构建的:
package com.example.helper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
public class RedCar {
private int age;
@Autowired
public RedCar (Environment env) {
this.age = new Integer(env.getRequiredProperty("car.age")).intValue();
}
@Override
public String toString() {
return "Car [age=" + age + "]";
}
}
YellowCar 的构建没有将环境变量传递给构造函数,而是使用了@Value 注释:
package com.example.helper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class YellowCar {
@Value("${car.age}")
private int age;
@Override
public String toString() {
return "YellowCar [age=" + age + "]";
}
}
这是程序输出:
Car [age=15]
YellowCar [age=0]
如您所见,YellowCar 的年龄未正确注入(它等于 0)。
我的目标:我不想将所有环境对象传递给其他 classes 的构造函数...我想改用 @Value annotatnio。有人可以解释我:
1)为什么我的代码不工作?
2) 应该如何更新此代码以获得以下输出?
Car [age=15]
YellowCar [age=15]
谢谢!
发生这种情况,因为您直接实例化了 YellowCar
。为了使事情工作, @Autowire
YellowCar
inside HelperApplication
并像这样使用这个注入的实例(未测试):
@Autowired
private YellowCar yellowCar;
public static void main(String[] args) {
SpringApplication.run(HelperApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println (new RedCar(env));
System.out.println (yellowCar);
}
解释:
当您使用 new 创建 class 时,Spring 对这个新实例一无所知,因此,它无法注入任何东西。但是当通过 Spring 基础结构创建实例时(我在这里尽量不使用很多俚语),它将注入所有字段:当您使用 @Component
注释标记 class 或使用 @Bean
注释创建方法,您告诉 Spring,您希望它是一个 Bean。在应用程序启动时,spring 创建此 bean 的实例 - 默认情况下每个上下文只有一个实例 - 并在请求时将此实例注入所有其他 bean。在这种情况下,这个实例正在由 spring 基础设施处理(确切的 class 是这样做的 - AutowiredAnnotationBeanPostProcessor
),其他 bean 的实例将被注入到我们的 bean 中。
UPD: 你可以用 RedCar
:
做同样的事情
@Autowired
private YellowCar yellowCar;
@Autowired
private RedCar redCar;
public static void main(String[] args) {
SpringApplication.run(HelperApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println (redCar);
System.out.println (yellowCar);
}
我正在学习 Spring Boot,我的问题可能很简单,但对我来说还不够清楚。我在使用 @Value 注释时遇到了一些问题 - 我想知道为什么应用程序 属性 不能注入到 class 参数。
我使用 Spring Initializr 准备了一些非常基本的项目,并向我的 "application.properties" 资源添加了一个 属性。此外,我创建了两个额外的 classes:"YellowCar"(工作正常)和 "RedCar"(不起作用 - 无法正确注入参数)。
"application.properties" 文件:
car.age=15
我申请的主要class:
package com.example.helper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;
@SpringBootApplication
public class HelperApplication implements CommandLineRunner {
@Autowired
private Environment env;
public static void main(String[] args) {
SpringApplication.run(HelperApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println (new RedCar(env));
System.out.println (new YellowCar());
}
}
RedCar 是通过将环境变量传递给构造函数来构建的:
package com.example.helper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
public class RedCar {
private int age;
@Autowired
public RedCar (Environment env) {
this.age = new Integer(env.getRequiredProperty("car.age")).intValue();
}
@Override
public String toString() {
return "Car [age=" + age + "]";
}
}
YellowCar 的构建没有将环境变量传递给构造函数,而是使用了@Value 注释:
package com.example.helper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class YellowCar {
@Value("${car.age}")
private int age;
@Override
public String toString() {
return "YellowCar [age=" + age + "]";
}
}
这是程序输出:
Car [age=15]
YellowCar [age=0]
如您所见,YellowCar 的年龄未正确注入(它等于 0)。
我的目标:我不想将所有环境对象传递给其他 classes 的构造函数...我想改用 @Value annotatnio。有人可以解释我: 1)为什么我的代码不工作? 2) 应该如何更新此代码以获得以下输出?
Car [age=15]
YellowCar [age=15]
谢谢!
发生这种情况,因为您直接实例化了 YellowCar
。为了使事情工作, @Autowire
YellowCar
inside HelperApplication
并像这样使用这个注入的实例(未测试):
@Autowired
private YellowCar yellowCar;
public static void main(String[] args) {
SpringApplication.run(HelperApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println (new RedCar(env));
System.out.println (yellowCar);
}
解释:
当您使用 new 创建 class 时,Spring 对这个新实例一无所知,因此,它无法注入任何东西。但是当通过 Spring 基础结构创建实例时(我在这里尽量不使用很多俚语),它将注入所有字段:当您使用 @Component
注释标记 class 或使用 @Bean
注释创建方法,您告诉 Spring,您希望它是一个 Bean。在应用程序启动时,spring 创建此 bean 的实例 - 默认情况下每个上下文只有一个实例 - 并在请求时将此实例注入所有其他 bean。在这种情况下,这个实例正在由 spring 基础设施处理(确切的 class 是这样做的 - AutowiredAnnotationBeanPostProcessor
),其他 bean 的实例将被注入到我们的 bean 中。
UPD: 你可以用 RedCar
:
@Autowired
private YellowCar yellowCar;
@Autowired
private RedCar redCar;
public static void main(String[] args) {
SpringApplication.run(HelperApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println (redCar);
System.out.println (yellowCar);
}