Внедрение beans в класс вне управляемого контекста Spring

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

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

Ответ 1

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

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

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

Ответ 2

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

A → B → C → x → y → Z

A, B, C управляются spring beans (создаются и управляются инфраструктурой spring) x, y - действительно простые POJO, созданные вашим приложением без помощи 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()

HTH - Yonatan

Ответ 3

Поиск бесконечных комбо-вложений autwire spring bean в pojo applicationcontextaware beanaware и т.д. обменивал меня назад, но это не обеспечило мне достаточно полного решения.

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

Доступ к spring Beans извне spring Контекст

Ответ 4

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

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

Ответ 5

Один из способов принести bean в Spring, несмотря на то, что его изготовление является внешним, заключается в использовании класса-помощника, помеченного как @Configuration bean, который имеет метод (помеченный @Bean), который фактически делает экземпляр и передает его обратно через Spring (который делает свою инъекцию свойств и создание прокси в этой точке).

Я не совсем уверен, какой объем вам нужен; с prototype, вы получите свежий bean в каждом месте.

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

Ответ 7

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

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

Object externalObject = ...
GenericApplicationContext parent = new StaticApplicationContext();
parent.getBeanFactory().registerSingleton( "externalObject", externalObject );
parent.refresh();
ApplicationContext appContext = new ClassPathXmlApplicationContext( ... , parent);