@Configurable не работает для объектов, инициализированных в методах @PostConstruct.

Я использую Spring с AspectJ через плетение во время компиляции, чтобы использовать аннотацию @Configurable spring для объектов, не управляемых контейнером.

Вот пример объекта с аннотацией @Configurable:

@Configurable(autowire = Autowire.BY_TYPE)
public class TestConfigurable {

    private TestComponent component;

    public TestComponent getComponent() {
        return component;
    }

    @Autowired
    public void setComponent(TestComponent component) {
        this.component = component;
    }
}

Компонент, который я ввожу в этот объект:

@Component
public class TestComponent {}

Когда я создаю TestConfigurable после создания контекста, TestComponent вводится туда нормально, но когда я делаю это из метода, аннотированного @PostConstruct, автопроводка не происходит.

Компонент с @PostConstruct:

@Component
public class TestPostConstruct {

    @PostConstruct
    public void initialize() {
        TestConfigurable configurable = new TestConfigurable();
        System.out.println("In post construct: " + configurable.getComponent());
    }
}

Приложение, которое я выполняю:

public class TestApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("/application-context.xml");
        applicationContext.registerShutdownHook();

        TestConfigurable configurable = new TestConfigurable();
        System.out.println("After context is loaded: " + configurable.getComponent());
    }
}

Вот вывод, который производит это приложение:

In post construct: null
After context is loaded: paulenka.aleh.roguelike.sandbox.TestComponent@fe18270

Итак, существует ли какой-либо обходной путь для внедрения зависимостей в объекты @Configurable, созданные внутри методов @PostConstruct? Все bean-компоненты с аннотациями @Component уже находятся в контексте, и автосвязывание для них уже выполнено вовремя, когда @PostConstruct называется. Почему Spring здесь не делает автовайринг?..

Могу выложить другие конфигурационные файлы (context и pom.xml), если они помогут решить проблему.

Обновление 1: Похоже, я нашел причину проблемы. Объекты, аннотированные @Configurable, инициализируются AnnotationBeanConfigurerAspect, который реализует BeanFactoryAware. Этот аспект использует BeanFactory для инициализации bean-компонентов. Похоже, что метод @PostConstruct объекта TestPostConstruct выполняется до того, как для BeanFactory установлено значение AnnotationBeanConfigurerAspect. Если средство ведения журнала настроено на отладку, на консоль выводится следующее сообщение: "BeanFactory не был установлен на ...: Убедитесь, что этот конфигуратор работает в контейнере Spring. Невозможно настроить компонент типа [...]. Продолжается без инъекции."

Вопрос, есть ли обходной путь, для меня все еще открыт...


person ixi    schedule 01.12.2014    source источник
comment
На самом деле это не решение проблемы, но вместо использования @Configurable вы можете просто внедрить фабрику в свой компонент.   -  person Dirk Lachowski    schedule 02.12.2014


Ответы (1)


Я нашел один обходной путь к этому. Чтобы инициализировать аспект AnnotationBeanConfigurerAspect перед выполнением @PostConstruct, вы можете добавить следующую аннотацию к классу с таким методом @PostConstruct:

@DependsOn("org.springframework.context.config.internalBeanConfigurerAspect")

Надеюсь, эта информация будет для кого-то полезной.

person ixi    schedule 02.12.2014
comment
Если вы считаете, что это правильный ответ, вы можете принять свой собственный ответ, чтобы закрыть вопрос. - person kriegaex; 03.12.2014