Java 使用xml配置在spring引导中有条件地加载bean?

Java 使用xml配置在spring引导中有条件地加载bean?,java,spring,spring-boot,Java,Spring,Spring Boot,我使用的是SpringBoot2.1 我的项目中有一些混合配置:XML文件和带有注释的java类。 我们目前的配置是: application.properties: spring.profiles.active=dev, component1, component2 spring.profiles.active=dev component1=true component2=true applicationContext-file.xml: <?xml version="1.0" e

我使用的是SpringBoot2.1

我的项目中有一些混合配置:XML文件和带有注释的java类。 我们目前的配置是:

application.properties:

spring.profiles.active=dev, component1, component2
spring.profiles.active=dev
component1=true
component2=true
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>   
如何在applicationContext-file.xml中调节myserviceimpl bean的实例化? 我不能再依赖profile属性,因为spring.profiles.active属性不再包括 组件的值


谢谢你的帮助。

我自己还没有试过,但我建议检查以下几点:

步骤1

为每个概要文件创建一个XML文件(例如,
dev
prod
,以便于示例):

app-config-dev.xml:
------------------
app-config-prod.xml:
------------------
步骤2

现在,在“主”应用程序context-file.xml中,不要直接定义bean,而是包含在步骤1中创建的所有xml文件:

<import resource="classpath:app-config-dev.xml" /> 
<import resource="classpath:app-config-prod.xml" /> 

  • 如果需要,请阅读此步骤的更多详细信息
步骤3

从应用程序属性中删除
component1=true
component2=true
,您不再需要它,配置文件本身定义了应该加载哪些bean

更新1

根据OP的第一条评论:

<>你可能会尝试另一种选择,但我认为它是一种“低层次”的解决方案,它需要深入理解弹簧加载过程是如何在引擎盖下工作的。 因此,当spring启动时,它会找到bean的定义(在xml、java配置、诸如
@Component
等注释中),并从所有这些信息中创建一个
BeanDefinition
——一个元数据对象,该对象聚合了关于bean的所有信息(例如,它的单例或原型)。此时还没有创建bean。让我们把这个时间点称为“Bean Definitions Done”点(为了便于解释,这是我头脑中的术语

然后spring开始构建依赖关系图,开始创建bean,初始化它们(自动连接、后期构造方法等),并将它们放到应用程序上下文中(如果它们是单例的话)

现在,在spring中有一个选项可以提供一个名为
BeanFactoryPostProcessor
的钩子,该钩子在“Bean定义完成”点被调用。这基本上是一个实现某些接口的java代码,本身就是spring以特殊方式处理的spring Bean

因此,您可以实现该接口并操作Bean工厂的结果。 也就是说,您可以访问spring打开的每个bean定义,如果您认为不应该创建此定义的bean(这里是您的自定义逻辑,它将检查属性,不管什么),请从注册表中删除bean定义: 有关删除bean定义的技术方法,请参阅


是一个Bean Factory后处理器的示例,它实际上添加了一个新的Bean,尽管它没有注册

无论如何,您可以为该Bean定义一个组件扫描上下文?这样您可以依赖conditionalonproperty注释。我知道conditionalonproperty注释,但我们无意迁移该XML文件现在是一个带注释的bean。有人有其他想法吗?谢谢谢谢,但这不行,因为有两个主要原因:1)这会复制文件。大约有30个XML文件。2)属性component1和component2是必不可少的。有些bean是基于环境实例化的(开发人员、产品…)还有其他bean是根据application.properties中其他属性的值实例化的(例如component1和component2)。@CelinioFernandes,注意-请参阅另一个选项(更新1)。
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> 
<import resource="classpath:app-config-dev.xml" /> 
<import resource="classpath:app-config-prod.xml" />