How to do conditional auto-wiring in Spring?
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
@Importand@ComponentScan(and their XML counterparts) undergo property resolution (i.e. you can use${}).
How to do conditional auto-wiring in Spring?的更多相关文章
- Wiring in Spring: @Autowired, @Resource and @Inject 区别
refer:https://www.baeldung.com/spring-annotations-resource-inject-autowire 主要是查找顺序不一致: @Resource Mat ...
- 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 ...
- spring学习总结——高级装配学习一(profile与@Conditional)
前言: 在上一章装配Bean中,我们看到了一些最为核心的bean装配技术.你可能会发现上一章学到的知识有很大的用处.但是,bean装配所涉及的领域并不仅仅局限于上一章 所学习到的内容.Spring提供 ...
- Spring Framework 条件装配 之 @Conditional
Spring Framework 条件装配 之 @Conditional 前言 了解SpringBoot的小伙伴对Conditional注解一定不会陌生,在SpringBoot项目中,Conditio ...
- Spring Autowiring by AutoDetect
In Spring, "Autowiring by AutoDetect", means chooses "autowire by constructor" i ...
- Spring Autowiring by Constructor
In Spring, "Autowiring by Constructor" is actually autowiring by Type in constructor argum ...
- Spring Autowiring by Name
In Spring, "Autowiring by Name" means, if the name of a bean is same as the name of other ...
- Spring Autowiring by Type
In Spring, "Autowiring by Type" means, if data type of a bean is compatible with the data ...
- Spring Auto-Wiring Beans
In Spring framework, you can wire beans automatically with auto-wiring feature. To enable it, just d ...
- Spring boot 配置文件详解 (properties 和yml )
从其他框架来看 我们都有自己的配置文件, hibernate有hbm,mybatis 有properties, 同样, Spring boot 也有全局配置文件. Springboot使用一个全局的配 ...
随机推荐
- linux下几个常用软件
Ubuntu 软件包地址 https://packages.ubuntu.com/ 一. 字体 不管是雅黑还是宋体,从windows cp过来后, 直接双击打开并安装 二. Meld 可视的diff和 ...
- Asp.net MVC - 使用PRG模式(附源码)
阅读目录: 一. 传统的Asp.net页面问题 二.Asp.net MVC中也存在同样的问题 三.使用PRG模式 四.PRG模式在MVC上的实现 一. 传统的Asp.net页面问题 一个传统的Asp. ...
- Django时区的解释
https://segmentfault.com/q/1010000000405911
- JMeter执行压测输出HTML图形化报表(一)
一.应用场景 1.无需交互界面或受环境限制(linux text model) 2.远程或分布式执行 3.持续集成,通过shell脚本或批处理命令均可执行,生成的测试结果可被报表生成模块直接使用,便于 ...
- python--json、jsonpath
1.遇到一个问题:android返回的基本都是标准的json格式,当我们想要对层层嵌套的json中找到自己想要的字段并进行校验时 难道需要一层一层的解析?? 2.使用jsonpath list_3={ ...
- BZOJ2480 Spoj3105 Mod 数论 扩展BSGS
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2480.html 题目传送门 - BZOJ2480 题意 已知数 $a,p,b$ ,求满足 $a^x≡b ...
- c#代码文件上传和下载
public JsonResult UploadFile(DriverFileManager filem) { var hfc = Syste ...
- sql对于字符串的处理
- 亲和串 kmp
Problem Description 人随着岁数的增长是越大越聪明还是越大越笨,这是一个值得全世界科学家思考的问题,同样的问题Eddy也一直在思考,因为他在很小的时候就知道亲和串如何判断了,但是发现 ...
- HUE的自动化安装部署
HUE=Hadoop User Experience(Hadoop用户体验),直白来说就一个开源的Apache Hadoop UI系统,由Cloudera Desktop演化而来,最后Cloudera ...