0
点赞
收藏
分享

微信扫一扫

Spring中如何根据条件注入Bean

幸甚至哉歌以咏志 2022-04-05 阅读 68
java

目录

使用Spring表达式(SpEL)

 Property占位符

 Spring profiles

Post processor

条件注解


我们可以写一个简单的工厂类来实现条件注入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创建依赖bean可能是一种更好的方法: 

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

}

使用Spring表达式(SpEL)

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

 Property占位符

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

 Spring profiles

<!-- 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”,但该定义仍将在应用程序上下文中注册(并且在使用不合格的自动连接时会使您的生活更加困难)。您还可以通过@Profile注释将概要文件与@Component-based bean一起使用。

Post processor

Spring提供了许多钩子点和SPI,你可以在其中参与应用程序上下文生命周期。

BeanFactoryPostProcessor可以读取和更改bean定义(例如,属性占位符${}解析是通过这种方式实现的)。

BeanPostProcessor可以处理bean实例。可以检查新创建的bean并使用它(例如@Scheduled annotation processing就是这样实现的)。

MergedBeanDefinitionPostProcessor是bean后处理器的扩展,可以在实例化之前更改bean定义(@Autowired annotation processing就是这样实现的)。

条件注解

先来看下条件接口,所有条件注解,都是通过扩展Condtion接口实现的:

@FunctionalInterface
public interface Condition {
    boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}

@Conditional注解,就是利用Condition接口判断条件是否满足,来决定是否初始化并向容器注入Bean。

Spring中提供了一系列相关注解:

@ConditionalOnMissingBean:当指定Bean不存在时,才会创建当前类的Bean。
@ConditionalOnBean:当指定Bean存在时(@ConditionalOnBean(name=“dependedBean”)),才会创建当前类的Bean。
 

@Component
@ConditionalOnBean(name="dependedBean")
public class ToCreateBean {
    // ...
}


 

举报

相关推荐

0 条评论