Подтвердить что ты не робот

Почему Spring игнорирует аннотацию @DependsOn?

Я использую Spring 3.1.3 для webapp, используя конфигурацию XML с проверкой компонентов.

Я понял, что один из отсканированных компонентов должен быть инициализирован до нескольких других. На всех классах, которым нужна инициализация постконструкции, у меня есть аннотация @PostConstruct для метода.

Чтобы настроить порядок зависимостей, я изменил "@Component" на "@Component (" configData ")" в классе, который должен быть постконструирован перед другими. Затем я добавил "@DependsOn" ( "configData" ) "перед каждым определением класса, которое должно быть построено после" configData "bean.

Из того, что я прочитал, это все, что мне нужно для обеспечения порядка зависимостей.

Затем я построил все, установил точки останова и запустил приложение. Я ожидал попасть в точку останова в "configData" bean до любого из зависимых beans. Это не то, что произошло. Первая точка останова была в методе "init" одного из зависимых beans.

Затем я изменил свой "log4j.xml", чтобы установить "debug" в качестве уровня ведения журнала для "org.springframework" и повторить мой тест. Поведение точки останова было таким же, и мой журнал не показывал никакой отладочной информации о инициализации Spring (у меня есть отладка для инициализации log4j, поэтому я подтвердил, что у меня установлен DEBUG для "org.springframework" ).

Что я могу потерять?

Update:

Если это имеет значение, вот несколько скелетных примеров того, что я здесь делаю.

@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".

4b9b3361

Ответ 1

(От кого-то правильного, но теперь удаленного ответа)

Контракт @DependsOn гарантирует, что был создан bean, и были установлены свойства. Это не гарантирует, что будут вызываться какие-либо методы @PostConstruct.

Чтобы заставить это работать, нужно, чтобы класс "зависимый" (класс, от которого зависят другие) реализовал класс "InitializingBean", который требует реализации метода afterPropertiesSet(). Я поместил исходное тело моего метода init() в этот метод. Я проверил, что это выполняется перед любым из классов, которые зависят от этого.

Еще одна вещь, о которой упоминалось в первоначальном ответе, состоит в том, что если бы я определил свою "зависимую" bean в XML и использовал свойство "init-method", это БЫЛО выполнилось до любого из классов, которые зависят от этого, Я не подтвердил это.

Ответ 2

Я также затронул ту же проблему, но все еще не был должным образом разрешен. В документации к решению Spring говорится:

"Использование DependsOn на уровне класса не имеет эффекта, если не используется компонентное сканирование".

Вот почему аннотация @dependsOn не имеет эффекта.