简体   繁体   English

Autowired在Bean类的Spring中不起作用

[英]Autowired not working in Bean class Spring

I am trying to create a bean and instantiate the bean properties overriding default constructor and using an object of Environment [org.springframework.core.env.Environment] to fetch and assign properies from property file. 我正在尝试创建一个bean并实例化覆盖默认构造函数的bean属性,并使用Environment [org.springframework.core.env.Environment]对象从属性文件中获取并分配属性。

Below is my property file [mi.properties] 以下是我的属性文件[mi.properties]

mi.name=GB
mi.grade=13

Below is my Simple bean Class 以下是我的简单bean类

public class School implements EnvironmentAware {

private String schoolName;
private int schoolGrade;
private int totalStudents;

public School(Environment env) {
    this.schoolName = env.getProperty("mi.name", "MT");
    this.schoolGrade = env.getProperty("mi.grade", Integer.class, 10);
    this.totalStudents = env.getProperty("mi.total", Integer.class, 1000);
}

public School() {
    this.schoolName = this.env.getProperty("mi.name", "MT");
    this.schoolGrade = this.env.getProperty("mi.grade", Integer.class, 10);
    this.totalStudents = this.env.getProperty("mi.total", Integer.class, 1000);
}
//Getter Setters
}

Below is my Java config class 下面是我的Java配置类

@Configuration
@PropertySource("classpath:/cross/mi.properties")
public class JavaConfig {
@Autowired
private Environment env;

@Bean
public School getSchool()
{
    School obj = new School(env);
    return obj;
}
}

This would create School bean properly . 这样可以正确创建School bean。 However when I try to autowire Environment in School bean it is not creating bean. 但是,当我尝试在School bean中自动连接Environment时,它不是在创建bean。

Below is what I have tried 以下是我尝试过的

public class School implements EnvironmentAware {

private String schoolName;
private int schoolGrade;
private int totalStudents;

@Autowired
private Environment env;

public School(Environment env) {
    this.schoolName = env.getProperty("mi.name", "MT");
    this.schoolGrade = env.getProperty("mi.grade", Integer.class, 10);
    this.totalStudents = env.getProperty("mi.total", Integer.class, 1000);
}

public School() {
    this.schoolName = this.env.getProperty("mi.name", "MT");
    this.schoolGrade = this.env.getProperty("mi.grade", Integer.class, 10);
    this.totalStudents = this.env.getProperty("mi.total", Integer.class, 1000);
}
//Getter Setters
}

And Java config changed as below 和Java配置更改如下

@Configuration
@PropertySource("classpath:/cross/mi.properties")
@ComponentScan
public class JavaConfig {
@Bean
public School getSchool()
{
    School obj = new School();
    return obj;
}
}

This is not creating School bean in Spring context and when I debugged, Environment instance inside overridden default constructor is null hence getProperty() method is failing. 这不是在Spring上下文中创建School bean,当我调试时,覆盖的默认构造函数中的Environment实例为null,因此getProperty()方法失败。

I am bit confused on this . 我对此有些困惑。

  1. As per my understanding the Spring life cycle context would autowire all @autowired properties before constructor call . 根据我的理解,Spring生命周期上下文将在构造函数调用之前自动连接所有@autowired属性。 Is it correct ? 这是正确的吗 ?

  2. If above statement in wrong when all autowired properties are resolved in spring life cycle? 在弹簧生命周期中解决所有自动装配的属性后,如果上述说法有误?

  3. As per JVM architecture , it allocates memory and assign default value to properties of a class when class is loaded for first time . 根据JVM体系结构,它在第一次加载类时会分配内存并为该类的属性分配默认值。 Does this means by default when School class is loaded its property env is defaulted to null ? 这是否默认意味着在加载School类时,其属性env默认为null?

  4. How autowired Environment in JavaConfig class is working ? JavaConfig类中的自动装配环境如何工作? How Spring autowires this values and in what stage of its life cycle ? Spring如何自动连接此值以及在其生命周期的哪个阶段?

As suggested in some forums I have tried implementing EnvironmentAware interface in School class and added @Component annotation to School class.Still No result. 由于在一些论坛上建议我曾尝试推行学校类EnvironmentAware接口,并添加注释@Component 学校 class.Still没有结果。

Spring injects @Autowired properties using reflection after constructor is executed and the instance is created. 在构造函数执行并创建实例之后,Spring使用反射注入@Autowired属性。 That's why you always get null in the constructor - the properties of the class are not set by Spring yet. 这就是为什么您总是在构造函数中获得null的原因-Spring尚未设置类的属性。

You can achieve what you want in a several ways. 您可以通过多种方式实现所需的目标。 One would be to use the 一种是使用

afterPropertiesSet() method which is executed as the name says after the properties are set :) There you will have env afterPropertiesSet()方法,正如设置属性后名称所执行的那样:)在那里,您将拥有env

Another solution which would be the preferred one by me is to add the autowired beans in the constructor. 对我而言,首选的另一种解决方案是在构造函数中添加自动装配的bean。 Some people call it constructor injection. 有人称其为构造函数注入。

It would be marking the constructor using Environment as autowired like that (or having just one constructor): 它将使用Environment将构造器标记为这样的自动装配(或只有一个构造器):

@Autowired
public School(Environment env) {
    this.schoolName = env.getProperty("mi.name", "MT");
    this.schoolGrade = env.getProperty("mi.grade", Integer.class, 10);
    this.totalStudents = env.getProperty("mi.total", Integer.class, 1000);
}

This way you can also set your Environment variable as final (which would be a good idea). 这样,您还可以将Environment变量设置为final(这是一个好主意)。 This will work with the @component annotation as other have suggested in order to remove the manual creation of bean using new School() 这将与其他建议的@component注释一起使用,以便使用new School()删除手动创建的bean。

Check this link for more 检查此链接了解更多

Injection happens after construction, unless you explicitly use constructor injection: 注入发生在构造之后,除非您明确使用构造函数注入:

@Autowired
public School(Environment env) {
    this.schoolName = env.getProperty("mi.name", "MT");
    this.schoolGrade = env.getProperty("mi.grade", Integer.class, 10);
    this.totalStudents = env.getProperty("mi.total", Integer.class, 1000);
}

Another option is to use a @PostConstruct method to do your initialising instead: 另一种选择是使用@PostConstruct方法代替进行初始化:

@Autowired
private Environment env;

public School() {
}

@PostConstruct
public void initialise() {
    this.schoolName = this.env.getProperty("mi.name", "MT");
    this.schoolGrade = this.env.getProperty("mi.grade", Integer.class, 10);
    this.totalStudents = this.env.getProperty("mi.total", Integer.class, 1000);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM