Условно загрузить бин в весеннюю загрузку, используя конфигурацию xml? - PullRequest
0 голосов
/ 05 февраля 2020

Я использую Spring Boot 2.1.

У меня в проекте смешанная конфигурация: XML файлы и java классы с аннотациями. У нас есть текущая конфигурация, которая работает:

application.properties:

spring.profiles.active=dev, component1, component2

applicationContext-file. xml:

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd"
  profile="component1"> 
    <beans>
        <bean id="myserviceimpl"
            class="org.blabla.MyServiceImpl">
            <property name="mydao">
                <ref bean="mydao"></ref>
            </property>
        </bean>
    </beans>
</beans>   

Мы хотим извлечь компонент значения из свойства spring.profiles.active, поскольку они не имеют ничего общего со средой:

application.properties:

spring.profiles.active=dev
component1=true
component2=true

Как я могу обусловить создание экземпляра бина myserviceimpl внутри applicationContext-file. xml? Я больше не могу полагаться на атрибут профиля, поскольку свойство spring.profiles.active больше не включает значения компонентов.

Спасибо за помощь.

1 Ответ

0 голосов
/ 05 февраля 2020

Я не пробовал сам, но предлагаю проверить следующее:

Шаг 1

Создать один XML файл на профиль (скажем, dev и prod для примера):

app-config-dev.xml:
------------------

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd"
  profile="dev"> 
    <beans>
       <!-- here define only beans that you want to load in __dev__ environment -->
        <bean id="myserviceimpl"
            class="org.blabla.MyServiceImpl">
            <property name="mydao">
                <ref bean="mydao"></ref>
            </property>
        </bean>
    </beans>
</beans> 
app-config-prod.xml:
------------------

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd"
  profile="prod"> 
    <beans>
        <!-- here define only beans that you want to load in __production__ environment -->
        <bean id="myserviceimpl"
            class="org.blabla.MyServiceProdImpl">
            <property name="mydao">
                <ref bean="mydao"></ref>
            </property>
        </bean>
    </beans>
</beans> 

Шаг 2

Теперь в вашем "основном" applicationContext-файле. xml вместо непосредственного определения bean-компонентов, включите все xml файлы, которые вы создали на шаге 1:

<import resource="classpath:app-config-dev.xml" /> 
<import resource="classpath:app-config-prod.xml" /> 
  • Прочтите этот поток для получения более подробной информации на этом шаге при необходимости

Шаг 3

Удалите component1=true и component2=true из свойств приложения, он вам больше не нужен, Сам профиль определяет, какие компоненты должны быть загружены.

Обновление 1

Первый комментарий ОП на основе:

Возможно, вы можете попробовать другой вариант, но я его рассматриваю «низкоуровневое» решение, и оно требует глубокого понимания того, как пружинная нагрузка работает под капотом.

Итак, когда начинается весна, он находит определения bean-компонентов (в конфигурации xml, java, аннотации типа @Component и т. Д.) И создает из всей этой информации BeanDefinition - метаданные объект, который собирает всю информацию о бине (например, его синглтон или прототип). На данный момент никаких бобов еще не создано. Давайте назовем этот момент времени «точкой определения бинов» (для объяснений, мой термин у меня в голове ...

Затем Spring начинает строить график зависимостей и начинает создавать бины , инициализируя их (Autowiring, методы после конструирования и т. д.) и помещая их в контекст приложения (если они синглтоны).

Теперь весной есть возможность предоставить хук, называемый BeanFactoryPostProcessor который вызывается именно в точке «Bean Definitions Done». Это в основном код java, который реализует некоторый интерфейс и сам по себе является пружинным компонентом, который Spring обрабатывает особым образом.

Таким образом, вы можете реализовать этот интерфейс и манипулировать результатами фабрики бинов. А именно, вы можете получить доступ к каждому определению бина, которое открыла пружина, и если вы думаете, что бин этого определения не должен быть создан (вот ваш собственный лог c что бы проверить свойства, что угодно) - удалить определение bean-компонента из реестра: для технических Как удалить определения бинов см. в этой теме

Здесь - пример процессора Bean Factory Post, который фактически добавляет новый бин, хотя он не был зарегистрирован

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