Почему 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 не действует.

Другие вопросы по тегам