#java #jakarta-ee #ejb
#java #джакарта-ee #ejb
Вопрос:
В приведенном ниже примере мне нужно присвоить Bean2 атрибут Bean1. Атрибут является null
(см. Ниже). Кроме того, «@PostConstruct Bean2» печатается перед «После присвоения».
Есть ли способ убедиться, что экземпляр Bean2 создан перед присвоением значения в Bean1?
@Stateless
public class Bean1 {
@Inject
private Bean2 bean2;
String x;
@PostConstruct
private void init() {
x = "Some Value";
System.out.println("Before assignment");
bean2.setX(x);
System.out.println("After assignment");
}
}
@Stateless
public class Bean2 {
private String x;
public setX(String x) {
this.x = x;
}
@PostConstruct
private void init() {
System.out.println("@PostConstruct Bean2");
System.out.println(x); // <-- x is null
}
}
Ответ №1:
Это ожидаемое поведение, основанное на том, как вы все настроили. x
должно быть правильно установлено в Bean2
после развертывания всего ApplicationContext.
Чтобы понять, что происходит, обратите внимание, что Bean2
это зависимость для Bean1
. Это означает, что Spring не может создавать, Bean1
пока после Bean2
не будет создан. Таким образом, он создается Bean2
первым, и вы видите, что x
в init()
блоке null, потому что Bean1
он еще не был сконструирован, чтобы можно было установить его значение.
Позже, Bean1
будет сконструирован, его init()
метод будет вызван, и значение для x
в Bean2
будет правильно установлено. Но это происходит спустя долгое время после того, как Bean2
‘s @PostConstruct
уже завершено.
Комментарии:
1. Я не использую Spring, можете ли вы перефразировать свой ответ? Кроме того, как добиться передачи значения Bean1 в Bean2?
2.Независимо от используемой вами платформы внедрения зависимостей результат один и тот же. Как только все приложение будет запущено, значение для
x
будет правильным. Это просто не может быть корректным вBean2
методе@PostConstruct
, потому что этот метод может быть запущен только послеBean2
создания, но доBean1
создания. Таким образом, он попадает в своего рода «мертвую зону», где код, который его инициализировал, еще не может быть запущен. Но этот код в конечном итоге будет запущен, и значение будет хорошим после запуска всего приложения.3. Есть ли способ узнать в Bean1, что внедренный экземпляр Bean2 уже создан?
4. Вы знаете, что внутри
Bean1
этоBean2
уже создано, потому что код выдавал быNullPointerException
в строке,bean2.setX(x);
еслиbean2
бы было null. Тот факт, что код не запускается, является доказательством того, чтоBean1
создается правильно (при условии, что вы видите сообщения журнала, поступающие изBean1
init()
метода).5. Если я могу работать
bean2.setX(x)
в bean1 без каких-либо исключений, это означает, что Bean2 уже создан. Почему значение x не задано в Bean2? Кроме того, есть ли другой способ добиться этого?