Я придерживался простого рефакторинга с простого java до spring. Приложение имеет объект "Контейнер", который создает экземпляры своих частей во время выполнения. Позвольте мне объяснить с помощью кода:
public class Container {
private List<RuntimeBean> runtimeBeans = new ArrayList<RuntimeBean>();
public void load() {
// repeated several times depending on external data/environment
RuntimeBean beanRuntime = createRuntimeBean();
runtimeBeans.add(beanRuntime);
}
public RuntimeBean createRuntimeBean() {
// should create bean which internally can have some
// spring annotations or in other words
// should be managed by spring
}
}
В принципе, во время загрузки контейнер запрашивает у некоторой внешней системы информацию о количестве и конфигурации каждого RuntimeBean, а затем создает beans в соответствии с заданной спецификацией.
Проблема заключается в том, что обычно в spring
ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
Container container = (Container) context.getBean("container");
наш объект полностью настроен и содержит все зависимости. Но в моем случае я должен создать экземпляр некоторых объектов, которым также нужна инъекция зависимостей после выполнения метода load(). Как я могу это достичь?
Я использую java-config. Я уже пробовал сделать factory для RuntimeBeans:
public class BeanRuntimeFactory {
@Bean
public RuntimeBean createRuntimeBean() {
return new RuntimeBean();
}
}
ожидание @Bean для работы в так называемом режиме "lite". http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Bean.html К сожалению, я не нашел разницы в простом выполнении нового RuntimeBean(); Вот сообщение с аналогичной проблемой: Как получить beans, созданный FactoryBean spring, управляемый?
Существует также http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Configurable.html, но это похоже на молот в моем случае.
Я также попробовал ApplicationContext.getBean( "runtimeBean", args), где runtimeBean имеет область "Prototype", но getBean - это ужасное решение.
Upd1. Чтобы быть более конкретным, я пытаюсь реорганизовать этот класс: https://github.com/apache/lucene-solr/blob/trunk/solr/core/src/java/org/apache/solr/core/CoreContainer.java @see #load() и найти "return create (cd, false);"
UPD2. Я нашел довольно интересную вещь, названную "инъекцией метода поиска" в документации spring: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-lookup-method-injection
А также интересный jira билет https://jira.spring.io/browse/SPR-5192, где Фил Вебб говорит https://jira.spring.io/browse/SPR-5192?focusedCommentId=86051&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-86051, что javax.inject.Provider следует использовать здесь (это напоминает мне Guice).
Upd3. Существует также http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.html
UPD4. Проблема со всеми этими методами поиска заключается в том, что они не поддерживают передачу каких-либо аргументов. Мне также нужно передать аргументы, как я делал бы с applicationContext.getBean( "runtimeBean", arg1, arg2). Похоже, в какой-то момент он был исправлен с https://jira.spring.io/browse/SPR-7431
Обновление 5. В Google Guice есть опрятная функция, называемая AssistedInject. https://github.com/google/guice/wiki/AssistedInject