Хобрук: Ваш путь к мастерству в программировании

Добавление динамических компонентов в весенний веб-контекст

Мне нужно иметь возможность добавлять новые bean-компоненты в веб-контекст Spring (в любой области) для классов, которые могут быть определены, а могут и не быть определены в пути к классам во время компиляции.

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

Я немного читал о BeanFactoryPostProcessor, но не уверен, будет ли он работать в веб-контексте, и, если я правильно понимаю, он будет работать только до фактической загрузки экземпляров bean-компонента, а не после этого, или я ошибаюсь?

Мне не удалось найти информацию о том, как это сделать в AnnotationConfigWebApplicationContext, и, по крайней мере, в моем тесте все bean-компоненты, которые я создаю динамически, не внедряются в другие экземпляры, и даже если бы они были, я вижу только метод для регистрации Singleton beans, но не для других областей:

ctx.getBeanFactory().registerSingleton("dummy", dummy);

P.D.

Я нашел этот вопрос: Динамическое создание beans в Spring, но когда я пытаюсь добавьте любой bean-компонент, определение bean-компонента или построитель определения bean-компонента в веб-контекст, например, bean-компонент не загружается:

AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.setServletContext(servletContext);
ctx.refresh();
//
log.trace("Registering first test bean");
Test test = new Test();
test.setDummy("x1");
ctx.getBeanFactory().registerSingleton("myTestBean1", test);        

log.trace("Registering second test bean");
BeanDefinition testDef = new RootBeanDefinition(Test.class);        
testDef.setScope(BeanDefinition.SCOPE_SINGLETON);        
ctx.getBeanFactory().registerSingleton("myTestBean2", testDef);

Test dummy1 = (Test)ctx.getBean("myTestBean1");
Object dummy2 = ctx.getBean("myTestBean2");

log.trace("beans: 1: {}; 2: {}", dummy1, dummy2); //<--this works, but...
ctx.refresh();

ctx.register(MyConfig.class); //configuring other beans

... Когда я делаю это из другого bean-компонента, настроенного внутри MyConfig.class или аннотированного с помощью @Component (это может быть даже другой динамический компонент):

@Autowire Test myTestBean1;
//Or this:
Object a = this.ctx.getBean("myTestBean1"); //Or myTestBean2

Выдает исключение NoSuchBeanDefinitionException

Пожалуйста помогите!! Я много искал и не нашел никакой полезной информации, или, может быть, я нашел, но я не могу протестировать все, что я нахожу в Интернете, за такое короткое время, и документация spring кажется очень хорошей только для обычных случаев и конфигураций xml, а не для этих сумасшедших вещей, которые я пытаюсь сделать, а не для программной настройки.

06.09.2012

  • Интересно, не упростит ли явная обработка жизненных циклов объектов в коде Java? 06.09.2012

Ответы:


1

То, что вам нужно, не может быть выполнено, извините. Автомонтирование происходит при первоначальном создании bean-компонента. В вашем случае вы ожидаете подключить bean-компонент до того, как добавите его на фабрику, что, конечно, не сработает - Spring не путешествует во времени.

Я думаю, вам нужен заводской образец. В Spring вы можете отложить создание экземпляра bean-компонента до создаваемой вами фабрики, внедрив FactoryBean. Подробнее здесь:

06.09.2012
  • Спасибо, но в примере я создаю bean-компонент перед автоподключением его к другому bean-компоненту, я отредактировал вопрос, чтобы сделать его более ясным, хотя это выглядит интересно... посмотрю на это, если мне понадобится другой подход. 06.09.2012
  • @Lando В вашем примере вы начинаете с вызова ctx.refresh() во второй строке, который создает всю фабрику компонентов и обрабатывает все автоматические подключения. Это происходит до того, как вы сделаете что-то еще. Несмотря на это, ручная вставка bean-компонентов во время выполнения — это не то, как должен работать Spring. Я уверен, что вы можете заставить его работать как-то, но это не будет красиво. Если вам нужно отложить/отложить создание bean-компонента, вы должны работать с областями действия и/или фабриками и интерфейсами. 07.09.2012
  • Если я не вызываю обновление раньше, я получаю исключение IllegalStateException, я проверяю код, и он подтверждает, что фабрика не является нулевой при регистрации новых синглетонов. Проблема с фабриками заключается в том, что мне все равно нужно было бы определить имя компонента, поэтому Spring делегирует создание фабрике. У меня заканчиваются идеи :( 08.09.2012
  • @Lando Не работайте против структуры, работайте с ней. Вы пытаетесь сделать что-то, что противоречит замыслу и замыслу Spring. Уделите немного времени и подумайте о жизненном цикле каждого из ваших объектов и о том, что вы пытаетесь сделать, и вы увидите, что причина, по которой у вас заканчиваются идеи, заключается в том, что ваше основное предположение является обратным. 10.09.2012
  • Правильная ссылка на сообщение в блоге выглядит следующим образом: spring.io/blog/2011/ 09 08/что-са-фабрикабин 24.01.2014
  • Новые материалы

    Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
    каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

    Как настроить Selenium в проекте Angular
    Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..