Как внедрить зависимости в само-созданный объект в Spring?

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

public class MyClass {
    @Autowired private AnotherBean anotherBean;
}

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

MyClass obj = new MyClass();

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

applicationContext.injectDependencies(obj);

(Я думаю, что Google Guice имеет что-то вроде этого)

Ответы на вопрос(5)

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

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

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

 workplaylifecycle22 авг. 2019 г., 17:04
Нет, мы должны новый MyClass вручную.
 jsosnowski15 авг. 2015 г., 16:25
Это чистое решение, но требует немного больше усилий: вы должны либо использовать ткачество во время загрузки, как показано выше на iimuhin, либо добавить компилятор AspectJ в проект. Время загрузки, как следует из названия, приведет к дополнительным затратам во время выполнения.
 masstroy30 авг. 2014 г., 06:51
Galz666, твой метод выглядит намного чище для того, что я хочу сделать. Однако я не могу заставить его работать. У меня нет xml-файла, и я использую полностью конфигурацию Java. Есть ли эквивалент<context:spring-configured/> ?
 Igor Mukhin08 апр. 2015 г., 16:54

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

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

 Eric Wilson10 сент. 2012 г., 21:10
Ваш ответ неверен, а ваш «реальный вопрос» - это комментарий, а не ответ.

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

ответ @skaffman почти 10 лет, и это не значит, что он недостаточно хорош или не работаетОтвет @ glaz666 является кратким и не помог мне решить мою проблему, но указал мне верное направлениеМоя настройкаSpring Boot 2.0.3 сSpring Neo4j & Aop starts (что в любом случае не имеет значения)Создавать бин, когдаSpring Boot готов использовать@Configurable подход (используяApplicationRunner)Gradle & Eclipseмеры

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

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

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

Есть ли конфликт версийПочемуorg.springframework.context.annotation.aspect.* не доступенПравильно ли настроена ваша IDE?И т. Д.

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

AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean(manuallyCreatedInstance);
Решение Вопроса

Вы можете сделать это с помощью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.
}
 Dalton11 февр. 2016 г., 13:36
@Denis, если у MyBean есть зависимости, которые не нужны фактическому классу, вы регистрируете зависимости, которые на самом деле не существуют, просто для экземпляра класса, так что на самом деле нет никакой разницы.
 Vadim Kirilchuk20 янв. 2014 г., 20:25
Но что делать, если у меня есть два объекта, а первый - второй? Как autowire bean factory работает с зависимостями в этом случае?
 Rodney P. Barbati03 сент. 2015 г., 17:22
Я согласен - весна пересмотрела весь язык. Теперь мы используем интерфейсы как конкретные классы, методы как экземпляры классов и всевозможные сложные и трудоемкие методы выполнения того, что вы делали с новым и достойным дизайном.
 Rogério19 авг. 2016 г., 19:08
Я думаю, что ответ @ glaz666 намного чище / лучше, чем этот. Единственный недостаток использования@Configurable Я вижу, что Spring требует использования AspectJ под одеялом.
 Alireza Fattahi27 сент. 2016 г., 07:12
Это очень полезная возможность, и ответ довольно правильный. Некоторые фреймворки, такие как стойки 2, используют эту функцию дляautowire их бобы. Увидетьstackoverflow.com/questions/39706221/...
 Sean Patrick Floyd28 сент. 2010 г., 16:29
Хороший ответ (+1). Есть также второй метод, где вы можете влиять на то, как происходит автоматическое подключение:static.springsource.org/spring/docs/3.0.x/javadoc-api/org/...
 Denis04 апр. 2014 г., 00:25
Это на самом деле плохая картина. Если вы действительно так используете MyBean, почему бы не использовать конструктор с AnotherBean в качестве параметра. Что-то вроде:code частный бин @Autowired AnotherBean; public void doStuff () {MyBean obj = new MyBean (bean); }code, Похоже, что со всеми этими аннотациями люди действительно запутываются и просто не используют базовый шаблон, который был в java SDK с первого дня. :(
 workplaylifecycle22 авг. 2019 г., 18:13
на самом деле, об этом ничего не сказано в весенней рамочной справочной документации, почему

Ваш ответ на вопрос