Если у вас есть доступ к контексту Spring, вы можете получить AutowireCapableBeanFactory, который затем сможете использовать с любым компонентом, подобным этому:
ApplicationContext springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContextEvent.getServletContext());
AutowireCapableBeanFactory factory = springContext.get(AutowireCapableBeanFactory.class);
// this would instantiate and autowire a bean:
UserDAO userDAO = factory.createBean(UserDAO.class);
// this will autowire an already existing bean:
UserDAO manualUserDAO = new UserDAO();
factory.initializeBean(manualUserDAO, "beanNameIfNeeded");
Однако, если боб требует, чтобы он был автоматически подключен, прежде чем его можно будет использовать, я предпочитаю использовать первый механизм и помечать конструктор как закрытый / защищенный, чтобы убедиться, что он не может быть создан с помощью 'new', и принудительно заставить его быть создан через фабрику, как указано выше.
ОБНОВЛЕНИЕ 11/27/17
Мне лично не нравилось использовать фабрику каждый раз, когда я хотел создать экземпляр с автопроводкой. Особенно, если какой-то другой процесс создавал экземпляр, такой как десериализация из базы данных и т. Д.
Я закончил тем, что создал аспект для автоматической обработки автопроводки.
Во-первых, я создал аннотацию для пометки классов, которые я хотел автоматически подключать автоматически:
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface AutowireAfterCreation {
}
Затем я создал аспект, в котором для выполнения автопроводки используется точка «после строительства». К сожалению, я не смог определить точечный разрез, который был вызван только после того, как был завершен «последний» конструктор, но, кажется, не повредит автоматическое связывание несколько раз, по крайней мере, в моем случае.
public aspect AutowiringAfterCreation {
@Autowired
private AutowireCapableBeanFactory beanFactory;
/**
* After construction, autowire the instance.
* @param o Newly created object to be autowired.
*/
after(Object o) returning : target(o) && initialization((@AutowireAfterCreation *).new(..)) {
// this aspect will actually autowire the instance multiple times if the class is part of an inheritance
// Hierarchy. This is not optimal, but it should not hurt anything to autowire more than once.
// FUTURE: modify the aspect so it only runs once, regardless of how many constructor calls are necessary.
beanFactory.autowireBeanProperties(o, AutowireCapableBeanFactory.AUTOWIRE_NO, false);
beanFactory.initializeBean(o, "unused");
}
}
Затем мне пришлось рассказать Spring об аспекте, чтобы factoryBean автоматически подключался к самому аспекту:
<bean class="AutowiringOnDemand" factory-method="aspectOf"/>
Теперь я могу создать любой экземпляр и автоматически подключить его, просто добавив аннотацию:
@AutowireAfterCreation
public class TestEntity {
@Value("${some.config.value}")
private String value;
@Autowired
private TestRepository repository;
}
Наконец, все, что вам нужно сделать, это создать экземпляр, и он автоматически подключается после завершения работы конструкторов:
TestEntity entity = new TestEntity();
ОБНОВЛЕНИЕ 1/2/2018
Интерфейс ApplicationContext изменился, и get () был удален, но вы все равно можете использовать первый механизм, но вместо этого вам нужно вызвать getAutowireCapableBeanFactory ().
Итак, первые две строки в примере сверху для этого ответа теперь будут выглядеть так:
ApplicationContext springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContextEvent.getServletContext());
AutowireCapableBeanFactory factory = springContext.getAutowireCapableBeanFactory();