Как внедрить зависимости в само-созданный объект в Spring? - PullRequest
115 голосов
/ 28 сентября 2010

Допустим, у нас есть класс:

public class MyClass {
    @Autowired private AnotherBean anotherBean;
}

Затем мы создали объект этого класса (или какой-то другой каркас создал экземпляр этого класса).

MyClass obj = new MyClass();

Можно ли по-прежнему вводить зависимости? Что-то вроде:

applicationContext.injectDependencies(obj);

(я думаю, что в Google Guice есть что-то вроде этого)

Ответы [ 5 ]

171 голосов
/ 28 сентября 2010

Вы можете сделать это, используя autowireBean() метод AutowireCapableBeanFactory.Вы передаете ему произвольный объект, и Spring будет обращаться с ним как с чем-то, что он сам создал, и будет применять различные биты и кусочки автоматической проводки.

Чтобы получить AutowireCapableBeanFactory, просто выполните автоматическую передачу:

private @Autowired AutowireCapableBeanFactory beanFactory;

public void doStuff() {
   MyBean obj = new MyBean();
   beanFactory.autowireBean(obj);
   // obj will now have its dependencies autowired.
}
18 голосов
/ 20 октября 2010

Вы также можете пометить свой MyClass аннотацией @Configurable:

@Configurable
public class MyClass {
   @Autowired private AnotherClass instance
}

Затем во время создания он автоматически внедрит свои зависимости. Вы также должны иметь <context:spring-configured/> в контексте приложения xml.

3 голосов
/ 17 февраля 2018

Просто возникла такая же потребность, и в моем случае это была уже логика внутри неуправляемого Java-класса, не поддерживающего Spring, который имел доступ к ApplicationContext. Вдохновлен скаффманом. Решено:

AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean(manuallyCreatedInstance);
2 голосов
/ 19 июня 2018

Я хотел бы поделиться своим решением, которое следует @Configurable подходу, как briefly, упомянутое в @ glaz666 answer , потому что

  • Ответ @skaffman - почти 10 лет, и это не значит, что он недостаточно хорош или не работает
  • Ответ @ glaz666 является кратким и не помог мне решить мою проблему, но направил меня в правильном направлении

Моя настройка

  1. Spring Boot 2.0.3 с Spring Neo4j & Aop starts (что в любом случае не имеет значения)
  2. Создание компонента, когда Spring Boot готов, используя подход @Configurable (используя ApplicationRunner)
  3. Gradle & Eclipse

Steps

Мне нужно было выполнить следующие шаги, чтобы заставить его работать

  1. @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE, dependencyCheck = false), который нужно поместить поверх вашего Bean, который должен быть создан вручную. В моем случае Bean, который должен быть создан вручную, имеет сервисы @Autowired, следовательно, реквизиты вышеупомянутой аннотации.
  2. Аннотируйте основной XXXApplicaiton.java Spring Boot (или файл, отмеченный @SpringBootApplication) с помощью @EnableSpringConfigured и @EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)
  3. Добавьте зависимости в ваш файл сборки (т.е. build.gradle или pom.xml в зависимости от того, какой файл вы используете) compile('org.springframework.boot:spring-boot-starter-aop') и compile('org.springframework:spring-aspects:5.0.7.RELEASE')
  4. Новый + ваш Bean, который помечен @Configurable где угодно, и его зависимости должны быть автоматически подключены.

* Что касается пункта 3 выше, я знаю, что org.springframework.boot:spring-boot-starter-aop транзитивно вытягивает spring-aop (как показано здесь mavencentral ), но в моем случае Eclipse не удалось разрешить 1059 * аннотаций, следовательно, почему я явно добавил зависимость spring-aop в дополнение к стартеру. Если вы столкнулись с той же проблемой, просто объявите зависимость или отправляйтесь на поиски решения

  • Есть ли конфликт версий
  • Почему org.springframework.context.annotation.aspect.* недоступен
  • Правильно ли настроена ваша IDE
  • и т. Д.
0 голосов
/ 28 сентября 2010

Не без некоторых обходных путей, поскольку Spring ничего не знает об этом экземпляре.

Реальный вопрос: почему вы создаете экземпляры класса, в который вы хотите, чтобы зависимости вводились вручную, а не позволяете Spring управлять им? Почему класс не использует MyClass, вводя в него MyClass?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...