![](/img/trans.png)
[英]How to pass service bean into spring boot controller using xml configuration
[英]Conditionally load a bean in spring boot using xml configuration?
我正在使用 Spring Boot 2.1。
我的项目中有一些混合配置:XML 文件和带有注释的 Java 类。 我们有这个有效的当前配置:
应用程序属性:
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 属性中提取组件值,因为它们与环境无关:
应用程序属性:
spring.profiles.active=dev
component1=true
component2=true
如何在 applicationContext-file.xml 中调节 myserviceimpl bean 的实例化? 我不能再依赖 profile 属性,因为 spring.profiles.active 属性不再包含组件的值。
谢谢你的帮助。
我自己没有尝试过,但我建议检查以下内容:
第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-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 定义”点”(为了解释起见,这是我的术语……
然后 spring 开始构建依赖关系图并开始创建 bean,初始化它们(自动装配、后构造方法等)并将它们放置到应用程序上下文中(如果它们是单例)。
现在,在 spring 中有一个选项可以提供一个名为BeanFactoryPostProcessor
的钩子,该钩子恰好在“Bean Definitions Done”点调用。 这基本上是一个实现一些接口的java代码,它本身就是一个spring以特殊方式处理的spring bean。
所以你可以实现这个接口并操作Bean工厂的结果。 也就是说,您可以访问 spring 已打开的每个 bean 定义,并且如果您认为不应创建此定义的 bean(这里是您的自定义逻辑来检查属性,无论如何) - 从注册表中删除 bean 定义:对于技术方法删除 bean 定义请参阅此线程
这是一个 Bean Factory Post 处理器的例子,它实际上添加了一个新的 bean,虽然它没有注册
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.