ou can implement simple factory bean to do the conditional wiring. Such factory bean can contain complex conditioning logic:

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 }

Maybe a bit better approach is if you use factory bean to create the dependency bean in case you want to have only one such bean in your application context:

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

With SpEL there are many possibilities. Most common are system property based conditions:

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

Property placeholder

You can have property placeholder resolve your bean reference. The dependency name can be part of the application configuration.

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

Spring profiles

Usually the condition you want to evaluate means that a whole set of beans should or should not be registered. Spring profiles can be used for this:

<!-- 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>

Other methods can mark the bean definition as lazy-init="true", but the definition will be still registered inside application context (and making your life harder when using unqualified autowiring). You can also use profiles with @Component based beans via @Profile annotation.

Check ApplicationContextInitialier (or this example) to see how you can activate profiles programatically (i.e. based on your condition).

Java config

This is why Java based config is being so popular as you can do:

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

Of course you can use more or less all configuration methods in the java based config as well (via @Profile@Value or @Qualifier + @Autowired).

Post processor

Spring offers numerous hook points and SPIs, where you can participate in the application context life-cycle. This section requires a bit more knowledge of Spring's inner workings.

BeanFactoryPostProcessors can read and alter bean definitions (e.g. property placeholder ${}resolution is implemented this way).

BeanPostProcessors can process bean instances. It is possible to check freshly created bean and play with it (e.g. @Scheduled annotation processing is implemented this way).

MergedBeanDefinitionPostProcessor is extension of bean post processor and can alter the bean definition just before it is being instantiated (@Autowired annotation processing is implemented this way).


UPDATE Oct 2015

  • Spring 4 has added a new method how to do conditional bean registration via @Conditionalannotation. That is worth checking as well.

  • Of course there are numerous other ways with Spring Boot alone via its @ConditionalOn*.

  • Also note that both @Import and @ComponentScan (and their XML counterparts) undergo property resolution (i.e. you can use ${}).

How to do conditional auto-wiring in Spring?的更多相关文章

  1. Wiring in Spring: @Autowired, @Resource and @Inject 区别

    refer:https://www.baeldung.com/spring-annotations-resource-inject-autowire 主要是查找顺序不一致: @Resource Mat ...

  2. 69 Spring Interview Questions and Answers – The ULTIMATE List--reference

    This is a summary of some of the most important questions concerning the Spring Framework, that you ...

  3. spring学习总结——高级装配学习一(profile与@Conditional)

    前言: 在上一章装配Bean中,我们看到了一些最为核心的bean装配技术.你可能会发现上一章学到的知识有很大的用处.但是,bean装配所涉及的领域并不仅仅局限于上一章 所学习到的内容.Spring提供 ...

  4. Spring Framework 条件装配 之 @Conditional

    Spring Framework 条件装配 之 @Conditional 前言 了解SpringBoot的小伙伴对Conditional注解一定不会陌生,在SpringBoot项目中,Conditio ...

  5. Spring Autowiring by AutoDetect

    In Spring, "Autowiring by AutoDetect", means chooses "autowire by constructor" i ...

  6. Spring Autowiring by Constructor

    In Spring, "Autowiring by Constructor" is actually autowiring by Type in constructor argum ...

  7. Spring Autowiring by Name

    In Spring, "Autowiring by Name" means, if the name of a bean is same as the name of other ...

  8. Spring Autowiring by Type

    In Spring, "Autowiring by Type" means, if data type of a bean is compatible with the data ...

  9. Spring Auto-Wiring Beans

    In Spring framework, you can wire beans automatically with auto-wiring feature. To enable it, just d ...

  10. Spring boot 配置文件详解 (properties 和yml )

    从其他框架来看 我们都有自己的配置文件, hibernate有hbm,mybatis 有properties, 同样, Spring boot 也有全局配置文件. Springboot使用一个全局的配 ...

随机推荐

  1. MUI组件四:选择器、滚动条、单选框、区域滚动和轮播组件

    目录(?)[+]   1.picker(选择器) mui框架扩展了pipcker组件,可用于弹出选择器,在各平台上都有统一表现.poppicker和dtpicker是对picker的具体实现.*pop ...

  2. input按钮去掉默认样式

    border: 1px solid transparent; //自定义边框 outline: none; //消除默认点击蓝色边框效果

  3. 安卓编程资源文件string中对占位符的使用详解

    这里将为你详细介绍占位符的使用,将其学以致用,可以达到简化布局文件,减少字符串资源量. 1.在资源文件中的使用. 打开资源文件中的strings.xml文件,进行编辑.如下图所示: 图  1.0 2. ...

  4. 20165220 实验三 敏捷开发与XP实践 实验报告

    实验三 敏捷开发与XP实践-1 实验要求: 实验三 敏捷开发与XP实践 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成IDEA ...

  5. javascript 作用域详解

    作用域理解:定义的变量.函数生效的范围.javascript 有全局作用域和函数作用域两种.注:es6实现let 块级作用域不是js原生的,底层同样是通过var实现的.如果想了解具体细节,请访问bab ...

  6. Intellij IDEA 解决 Maven 依赖下载慢的问题

    最近用 IDEA 导入 Hadoop 源码, 但下载依赖特别慢.导致经常需要重启 IDEA 并且下载的过程非常艰难, 网上找了一些方法,各种尝试,终于解决了这个问题.本篇文章总结最关键的两点,希望能帮 ...

  7. 读取XML文件内容

    myeclipse中类的格式 上面中的RunMain.java为程序执行的入口,JdbcUtil.java为实体类,XmlDocumentUtil.java执行解释xml文件与获取里面的属性,程序所需 ...

  8. pyspider 启动错误

    [root@localhost python]# pyspider all [W 180629 07:08:26 run:413] phantomjs not found, continue runn ...

  9. Centos6.5部署Rsyslog+LogAnalyzer中文乱码解决

    中文乱码 [root@log include]# pwd /zhang/app/loganalyzer-/src/include [root@log include]# vim functions_c ...

  10. AE文件特别大

    解决AE的输出文件太大_百度经验 在渲染队列的输出组件中把格式选项改为H.264,然后你会得到一个MP4文件. 然后最关键的一步,打开格式选项,把目标比特率和最大比特率均设10(比特率越高,视频质量越 ...