Инъекция бобов в класс вне управляемого контекста Spring


Я конечный пользователь одного из продуктов моей компании. Он не очень подходит для интеграции в Spring, однако я могу получить дескриптор контекста и получить требуемый Боб по имени. Тем не менее, я все равно хотел бы знать, можно ли ввести боб в этот класс, даже если класс не управляется самой Spring.

уточнение: то же самое приложение, которое управляет жизненным циклом некоторого класса MyClass, также управляет жизненным циклом Весенний контекст. Spring не имеет никаких знаний об экземпляре MyClass, и я хотел бы, чтобы некоторые из них предоставляли экземпляр контексту, но не могут создать экземпляр в самом контексте.

7   51  

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);