gpt4 book ai didi

spring - 如何在 Spring 中进行条件 Autowiring ?

转载 作者:IT老高 更新时间:2023-10-28 13:02:37 25 4
gpt4 key购买 nike

有没有人尝试根据条件将不同的 bean 自动连接到 Spring 管理的 bean 中?例如如果满足某些条件,则注入(inject) A 类,否则注入(inject) B?我在其中一个 Google 搜索结果中看到,可以使用 SpEL(Spring 表达式语言),但找不到工作示例。

最佳答案

有多种方法可以实现这一目标。大多数情况下,这取决于您要执行的调节。

工厂 bean

您可以实现简单的工厂 bean 来进行条件连接。这样的工厂 bean 可以包含复杂的条件逻辑:

public MyBeanFactoryBean implements FactoryBean<MyBean> {

// Using app context instead of bean references so that the unused
// dependency can be left uninitialized if it is lazily initialized
@Autowired
private ApplicationContext applicationContext;

public MyBean getObject() {
MyBean myBean = new MyBean();
if (true /* some condition */) {
myBean.setDependency(applicationContext.getBean(DependencyX.class));
} else {
myBean.setDependency(applicationContext.getBean(DependencyY.class));
}
return myBean;
}

// Implementation of isSingleton => false and getObjectType

}

如果您希望在应用程序上下文中只有一个这样的 bean,则使用 factory bean 来创建 dependency bean 可能更好一点: p>

public MyDependencyFactoryBean implements FactoryBean<MyDependency> {

public MyDependency getObject() {
if (true /* some condition */) {
return new MyDependencyX();
} else {
return new MyDependencyY();
}
}

// Implementation of isSingleton => false and getObjectType

}

SpEL

SpEL 有很多可能性。最常见的是 system property基于条件:

<bean class="com.example.MyBean">
<property name="dependency" value="#{systemProperties['foo'] == 'bar' ? dependencyX : dependencyY}" />
</bean>

属性占位符

您可以让属性占位符解析您的 bean 引用。依赖项名称可以是应用程序配置的一部分。

<bean class="com.example.MyBean">
<property name="dependency" ref="${dependencyName}" />
</bean>

Spring 配置文件

通常,您要评估的条件意味着应该或不应该注册整套 bean。 Spring 配置文件可用于此:

<!-- Default dependency which is referred by myBean -->
<bean id="dependency" class="com.example.DependencyX" />

<beans profile="myProfile">
<!-- Override `dependency` definition if myProfile is active -->
<bean id="dependency" class="com.example.DependencyY" />
</beans>

其他方法可以将 bean 定义标记为 lazy-init="true",但该定义仍将在应用程序上下文中注册(并且在使用不合格的 Autowiring 时会让您的生活更加困难)。您还可以通过 @Profile 注释将配置文件与基于 @Component 的 bean 一起使用。

检查 ApplicationContextInitialier (或此 example )查看如何以编程方式激活配置文件(即基于您的条件)。

Java 配置

这就是为什么基于 Java 的配置如此受欢迎的原因:

@Bean
public MyBean myBean() {
MyBean myBean = new MyBean();
if (true /* some condition */) {
myBean.setDependency(dependencyX());
} else {
myBean.setDependency(dependencyY());
}
return myBean;
}

当然,您也可以在基于 java 的配置中使用或多或少的所有配置方法(通过 @Profile@Value@Qualifier + @Autowired)。

后处理器

Spring 提供了许多 Hook 点和 SPI,您可以在其中参与应用程序上下文的生命周期。本节需要更多地了解 Spring 的内部工作原理。

BeanFactoryPostProcessors 可以读取和更改 bean 定义(例如属性占位符 ${} 解析就是这样实现的)。

BeanPostProcessor 可以处理 bean 实例。可以检查新创建的 bean 并使用它(例如,@Scheduled 注释处理就是以这种方式实现的)。

MergedBeanDefinitionPostProcessorbean 后处理器 的扩展,可以在实例化之前更改 bean 定义(实现了 @Autowired 注释处理这样)。


2015 年 10 月更新

  • Spring 4 增加了一个新方法怎么办conditional bean registration通过 @Conditional注解。这也值得检查。

  • 当然,通过 @ConditionalOn* 单独使用 Spring Boot 还有许多其他方法。

  • 另请注意,@Import@ComponentScan(以及它们的 XML 对应项)都经过属性解析(即您可以使用 ${})。

关于spring - 如何在 Spring 中进行条件 Autowiring ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19225115/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com