自动装配不在Bean类Spring中工作

时间:2018-04-24 13:27:28

标签: java spring inversion-of-control autowired

我正在尝试创建一个bean并实例化覆盖默认构造函数的bean属性,并使用Environment [org.springframework.core.env.Environment]的对象从属性文件中获取和分配属性。

以下是我的属性文件[mi.properties]

mi.name=GB
mi.grade=13

下面是我的Simple bean Class

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
}

下面是我的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;
}
}

这将正确创建School bean。但是,当我尝试在学校bean中自动装配环境时,它不会创建bean。

以下是我的尝试

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
}

Java配置更改如下

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

这不是在Spring上下文中创建School bean,当我调试时,重写的默认构造函数中的Environment实例是 null 因此 getProperty()方法失败。

我对此感到有点困惑。

  1. 根据我的理解,Spring生命周期上下文会在构造函数调用之前自动装配所有@autowired属性。这是正确的吗?

  2. 如果在弹簧生命周期中解决了所有自动装配的属性,上面的语句是错误的吗?

  3. 根据JVM体系结构,它会在第一次加载类时分配内存并为类的属性分配默认值。这意味着默认情况下加载 School 类时,其属性 env 默认为null?

  4. JavaConfig类中的自动装配环境如何工作? Spring如何自动赋值这个值以及它的生命周期的哪个阶段?

  5.   
        

    正如在某些论坛中所建议的,我尝试在学校类中实现EnvironmentAware接口,并将@Component注释添加到学校类.Still No result。

      

2 个答案:

答案 0 :(得分:0)

Spring在执行构造函数并创建实例后使用反射注入@Autowired属性。这就是为什么你总是在构造函数中得到null的原因 - 类的属性还没有被Spring设置。

您可以通过多种方式实现自己想要的目标。一个是使用

afterPropertiesSet()方法,在设置属性后按名称执行:)在那里你将有env

另一个我最喜欢的解决方案是在构造函数中添加自动装配的bean。有些人称之为构造函数注入。

它会将使用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);
}

这样你也可以将你的Environment变量设置为final(这是一个好主意)。这将与其他人建议的@component注释一起使用,以便使用new School()删除bean的手动创建

查看此link了解更多

答案 1 :(得分:0)

构造之后会发生注入,除非您明确使用构造函数注入:

RegisterPropertyEditor

另一个选择是使用@PostConstruct方法进行初始化:

TBitmapItemTag TCollectionItem