Инъекция бобов в класс вне управляемого контекста Spring
Я конечный пользователь одного из продуктов моей компании. Он не очень подходит для интеграции в Spring, однако я могу получить дескриптор контекста и получить требуемый Боб по имени. Тем не менее, я все равно хотел бы знать, можно ли ввести боб в этот класс, даже если класс не управляется самой Spring.
уточнение: то же самое приложение, которое управляет жизненным циклом некоторого класса MyClass, также управляет жизненным циклом Весенний контекст. Spring не имеет никаких знаний об экземпляре MyClass, и я хотел бы, чтобы некоторые из них предоставляли экземпляр контексту, но не могут создать экземпляр в самом контексте.
7 ответов:
вы можете сделать это:
ApplicationContext ctx = ... YourClass someBeanNotCreatedBySpring = ... ctx.getAutowireCapableBeanFactory().autowireBeanProperties( someBeanNotCreatedBySpring, AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true);
можно использовать
@Autowired
и так далее в пределахYourClass
для указания полей для инъекций и т. д.
один из способов привести боб в весну, несмотря на то, что его производство является внешним, - использовать вспомогательный класс, помеченный как
@Configuration
боб, который имеет метод (с пометкой@Bean
), что фактически делает экземпляр и передает его обратно через Spring (который делает его инъекцию свойств и генерацию прокси в этот момент).Я не совсем уверен, какой объем вам нужен; с
prototype
, вы получите свежую фасоль в каждом месте.@Configuration public class FooBarMaker { @Bean(autowire = Autowire.BY_TYPE) @Scope("prototype") public FooBar makeAFooBar() { // You probably need to do some more work in here, I imagine return new FooBar(); } }
вы можете ввести свойства, необходимые для производство в
@Configuration
бобовые. (Я использую это для создания экземпляров интерфейса, где имя класса для создания экземпляра определяется во время выполнения.)
предположим, что u имеет следующую цепочку зависимостей:
A --> B -- > C -- > x -- > y -- > Z
а, б, к фасоли управляемые весной (построенные и manged рамками весны) x, y-это действительно простые POJOs, которые построены вашим приложением, без помощи spring
теперь, если вы хотите, чтобы y получил ссылку на Z с помощью spring, что вам нужно иметь "дескриптор" для spring ApplicationContext
один из способов сделать это заключается в реализации ApplicationContextAware интерфейс . В этом случае я бы предложил, чтобы A, B или C реализовали этот интерфейс и сохранили ссылку applicationContext в статическом члене.
Итак, давайте возьмем Класс C например:
class C implmenets ApplicationContextAware{ public static ApplicationContex ac; void setApplicationContext(ApplicationContext applicationContext) { ac = applicationContext; } ............. }
теперь, в классе y вы должны иметь:
(Z)(C.ac.getBean("classZ")).doSomething()
ХТ - Йонатан
Поиск бесконечных комбо autowire inject spring bean в pojo applicationcontextaware beanaware и т. д. окружил меня здесь, но это не обеспечило достаточно полного решения для меня.
Это гораздо лучшая реализация / учебник этого ИМО: Я надеюсь, что это помогает всем, как это, наконец, помогло мне.
другой способ сделать это-использовать AspectJ. Это рекомендуемый способ впрыска пружинных компонентов в неуправляемые объекты, которые создаются с помощью
new
оператора. Подробности и описание здесь:http://www.javacodegeeks.com/2011/02/domain-driven-design-spring-aspectj.html
будьте осторожны, что в самой старой версии Spring, есть потокобезопасная проблема с bean factory http://jira.springframework.org/browse/SPR-4672
Если вы хотите создать объект за пределами весенний контекст, и сделать этот объект доступным для инъекции в другие бобы, которые are в контексте Spring вы можете выполнить следующие действия в в этой статье.
в основном, вы создаете Родительский контекст приложения и помещаете свой внешний объект в этот родительский контекст как синглтон. Затем вы создаете основной контекст приложения (например, из xml-файлов) с родительским приложением контекст как его родитель.
Object externalObject = ... GenericApplicationContext parent = new StaticApplicationContext(); parent.getBeanFactory().registerSingleton( "externalObject", externalObject ); parent.refresh(); ApplicationContext appContext = new ClassPathXmlApplicationContext( ... , parent);