Java 使用xml配置在spring引导中有条件地加载bean?
我使用的是SpringBoot2.1 我的项目中有一些混合配置:XML文件和带有注释的java类。 我们目前的配置是: application.properties: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
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" />
- 如果需要,请阅读此步骤的更多详细信息
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" />