Автопроводка не работает в классе Bean Spring - PullRequest
0 голосов
/ 24 апреля 2018

Я пытаюсь создать компонент и создать экземпляр свойства компонента, переопределяющего конструктор по умолчанию и использующий объект Environment [org.springframework.core.env.Environment] для получения и назначения свойств из файла свойств.

Ниже находится мой файл свойств [mi.properties]

mi.name=GB
mi.grade=13

Ниже приведен мой класс бобов

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;
}
}

Это создаст Школьный бин правильно. Однако, когда я пытаюсь автоматически связать среду в школьном компоненте, он не создает компонент.

Ниже я попробовал

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;
}
}

Это не создает School bean в контексте Spring, и когда я отлаживал, экземпляр Environment внутри переопределенного конструктора по умолчанию имеет значение null , следовательно, getProperty () метод терпит неудачу.

Я немного запутался в этом.

  1. Согласно моему пониманию, контекст жизненного цикла Spring будет автоматически связывать все свойства @autowired перед вызовом конструктора. Это правильно?

  2. Если приведенное выше утверждение неверно, когда все свойства автопроводки разрешены в жизненном цикле весны?

  3. Согласно архитектуре JVM, он выделяет память и присваивает значение по умолчанию свойствам класса, когда класс загружается впервые. Означает ли это, что по умолчанию, когда School class загружен, его свойство env по умолчанию имеет значение null?

  4. Как работает автоматическая среда в классе JavaConfig? Как Spring автоматически связывает эти значения и на какой стадии своего жизненного цикла?

Как предлагалось на некоторых форумах, я попытался реализовать интерфейс EnvironmentAware в School class и добавил аннотацию @Component к School class.Still Нет результата.

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Внедрение происходит после построения, если только вы явно не используете инжектор конструктора:

@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);
}

Другой вариант - использовать метод @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);
}
0 голосов
/ 24 апреля 2018

Spring внедряет свойства @Autowired, используя отражение после выполнения конструктора и создания экземпляра.Вот почему вы всегда получаете null в конструкторе - свойства класса еще не установлены Spring.

Вы можете достичь того, чего хотите, несколькими способами.Можно было бы использовать метод

afterPropertiesSet(), который выполняется, как следует из названия после установки свойств :) Там у вас будет env

Другое решение, которое было бы предпочтительным помне нужно добавить автонастроенные бины в конструкторе.Некоторые люди называют это инжекцией конструктора.

Было бы пометить конструктор, используя 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.переменная как окончательная (что было бы хорошей идеей).Это будет работать с аннотацией @component, как предлагали другие, чтобы удалить создание компонента вручную, используя new School()

. Проверьте ссылку , чтобы узнать больше

...