Я использую 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. Невозможно настроить компонент типа [...]. Продолжается без инъекции."
Вопрос, есть ли обходной путь, для меня все еще открыт...
@Configurable
вы можете просто внедрить фабрику в свой компонент. - person Dirk Lachowski   schedule 02.12.2014