Почему Spring проигнорировал мою аннотацию @DependsOn?
Я использую Spring 3.1.3 для веб-приложения, использую конфигурацию XML с компонентным сканированием.
Я понял, что один из отсканированных компонентов должен быть инициализирован раньше, чем несколько других. На всех классах, которые требуют инициализации после конструирования, у меня есть аннотация @PostConstruct для метода.
Чтобы установить порядок зависимостей, я изменил "@Component" на "@Component("configData")" в классе, который нужно постстроить перед остальными. Затем я добавил '@DependsOn("configData") "перед каждым определением класса, которое должно быть построено после ПОСЛЕ компонента" configData ".
Из того, что я прочитал, это все, что мне нужно для обеспечения порядка зависимостей.
Затем я все собрал, установил точки останова и запустил приложение. Я ожидал достичь точки останова в bean-компоненте "configData" перед любым из зависимых bean-компонентов. Это не то, что случилось. Первая точка останова была в методе "init" одного из зависимых bean-компонентов.
Затем я изменил свой "log4j.xml", чтобы установить "debug" в качестве уровня ведения журнала для "org.springframework" и перезапустил свой тест. Поведение точки останова было таким же, и в моем журнале не было отладочной информации об инициализации Spring (у меня есть отладка для самой инициализации log4j, поэтому я подтвердил, что для DEBUG установлено значение "org.springframework").
Чего мне не хватает?
Обновить:
Если это имеет значение, вот пара скелетных примеров того, что я здесь делаю.
@Component("configData")
public class ConfigData {
....
@PostConstruct
public void init() {
....
}
}
@Component
@DependsOn("configData")
public class ClassDependentOnConfigData extends BaseClass {
....
@Override
@PostConstruct
public void init() {
super.init();
....
}
}
Еще раз повторю, что я нахожу во время выполнения, что метод "init()" в "ClassDependentOnConfigData" вызывается Spring перед методом "init()" в "ConfigData".
Также обратите внимание, что "BaseClass" имеет "@Autowired" для "ConfigData".
2 ответа
(От чьего-то правильного, но сейчас удаленного ответа)
Контракт @DependsOn гарантирует только то, что бин был создан и свойства установлены. Это не гарантирует, что были вызваны какие-либо методы @PostConstruct.
Чтобы заставить это работать, нужно, чтобы класс "dependee" (класс, от которого зависят другие) реализовал класс "InitializingBean", который требует реализации метода "afterPropertiesSet()". Я поместил оригинальное тело моего метода "init()" в этот метод. Я проверил, что это теперь выполняется перед любым из классов, которые зависят от этого.
Еще одна вещь, которая была упомянута в первоначальном ответе, состоит в том, что, если бы я определил мой bean-компонент "dependee" в XML и использовал свойство "init-method", это БЫЛО выполнено перед любым из классов, которые зависят от этого. Я не проверял это.
Я также столкнулся с той же проблемой, но все еще не решен должным образом. В составе решения Spring документация гласит:
"Использование DependsOn на уровне класса не имеет никакого эффекта, если не используется компонентное сканирование".
По этой причине аннотация @dependsOn не действует.