Внедрение bean-компонентов в класс вне управляемого контекста Spring - PullRequest
53 голосов
/ 22 ноября 2008

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

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

Ответы [ 7 ]

55 голосов
/ 04 сентября 2009

Вы можете сделать это:

ApplicationContext ctx = ...
YourClass someBeanNotCreatedBySpring = ...
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(
    someBeanNotCreatedBySpring,
    AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true);

Вы можете использовать @Autowired и т. Д. В YourClass, чтобы указать поля для ввода и т. Д.

2 голосов
/ 13 августа 2013

Один из способов перенести бин в Spring, несмотря на то, что его производство является внешним, - это использовать вспомогательный класс, помеченный как бин @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 можно вводить свойства, необходимые для производства. (Я использую это для создания экземпляров интерфейса, в котором имя создаваемого класса определяется во время выполнения.)

2 голосов
/ 23 ноября 2008

предположим, что у вас есть следующая цепочка зависимостей:

A -> B -> C -> x -> y -> Z

A, B, C - бобы с пружинным управлением (сконструированы и управляются с помощью пружинных рамок) x, y - действительно простые POJO, созданные вашим приложением без помощи пружины

Теперь, если вы хотите, чтобы y получал ссылку на Z с помощью пружины, вам необходимо иметь «дескриптор» для пружины 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()

HTH - Йонатан

1 голос
/ 13 августа 2013

Другой способ сделать это - использовать AspectJ. Это рекомендуемый способ внедрения бинов Spring в неуправляемые объекты, созданные с помощью оператора new. Смотрите это для деталей:

http://www.javacodegeeks.com/2011/02/domain-driven-design-spring-aspectj.html

1 голос
/ 17 февраля 2012

Поиск бесконечных комбо из autowire inject spring bean в pojo applicationcontextawareware beanaware и т.д. окружил меня, но это не дало мне достаточно полного решения.

Это намного лучшая реализация / учебное пособие по этой ИМО: Я надеюсь, что это помогает всем, как это наконец помогло мне.

Доступ к Spring Bean извне Spring Context

0 голосов
/ 07 марта 2014

Если вы хотите создать объект вне контекста Spring и сделать этот объект доступным для инъекции в другие компоненты, которые равны в контексте Spring, вы можете выполнить шаги в эта статья .

По сути, вы создаете родительский контекст приложения и помещаете свой внешний объект в этот родительский контекст как одиночный объект. Затем вы создаете основной контекст приложения (например, из XML-файлов) с родительским контекстом приложения в качестве родительского.

Object externalObject = ...
GenericApplicationContext parent = new StaticApplicationContext();
parent.getBeanFactory().registerSingleton( "externalObject", externalObject );
parent.refresh();
ApplicationContext appContext = new ClassPathXmlApplicationContext( ... , parent);
0 голосов
/ 23 ноября 2008

Обратите внимание, что в самой старой версии Spring существует проблема с безопасностью потока с фабрикой бинов http://jira.springframework.org/browse/SPR-4672

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