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.
BeanFactoryPostProcessor
s can read and alter bean definitions (e.g. property placeholder ${}
resolution is implemented this way).
BeanPostProcessor
s 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
@Conditional
annotation. 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?的更多相关文章
- 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使用一个全局的配 ...
随机推荐
- 【C#】使用OWIN创建Web API
OWIN的介绍 OWIN 的全称是 "Open Web Interface for .NET", OWIN 在 .NET Web 服务器和 .NET Web 应用之间定义了一套标准 ...
- 【AtCoder】AGC016
A - Shrinking 用每个字母模拟一下就行 #include <bits/stdc++.h> #define fi first #define se second #define ...
- 关于appium-doctor运行时提示不是内部或外部的命令
1.一定要单独配置android_home (我之前是直接将D:\SDK\platform-tools;D:\SDK\tools;加到path里面会导致appnium-doctor运行时失败,原因为A ...
- 了解一下vue源码中vue 的由来
我们之前提到过 Vue.js 构建过程,在 web 应用下,我们来分析 Runtime + Compiler 构建出来的 Vue.js,它的入口是 src/platforms/web/entry-r ...
- webpack的build的时候时间长处理方案
观察第一次build的时间比较长,之后的编译时间较短,可以通过webpack -watch 监测性能 1, 将webpack升级到4.0,build 的速度提升很多 2,用webpack -watch ...
- 将linux系统目录挂载到其他分区,扩大系统可用空间
刚看到有小白用户说linux系统盘分区太小,不够用,问是不是要重装系统? 其实是不需要重装系统的,可以考虑把一些系统目录挂载到单独的分区. 比如将用户目录 /home 挂载到单独的分区: 1.首先打开 ...
- 004.NTP多层级架设
一 环境需求 1.1 需求 User-client:局域网所有节点主机: IN-NTP Server:隐藏于局域网内部的NTP服务器: Border-NTP:边界NTP服务器,用于同步外部时钟,同时对 ...
- 安装win7出现安装程序无法创建新的系统分区
安装win7的时候出现“安装程序无法创建新的系统分区 也无法定位系统分区”! 我是直接把一个系统碟里面的安装文件全部拷出来.放到要安装系统的机器(D盘).用的是老毛桃的winpe已经安装好了.我的安装 ...
- OSPF补全计划-2
想起来几个面试题: 1. OSPF在什么情况下会stuck in Exstart /Exchange状态? 我知道的一个答案是两个端口的mtu不一致.当然整个也不是绝对,因为可以用ip ospf mt ...
- [OC] @property时,copy、strong、weak、assign的区别
@property(copy,nonatomic)NSMutableString*copyStr; @property(strong,nonatomic)NSMutableString*strongS ...