我們知道,spring boot自動(dòng)配置功能可以根據(jù)不同情況來決定spring配置應(yīng)該用哪個(gè),不應(yīng)該用哪個(gè),舉個(gè)例子:
- spring的jdbctemplate是不是在classpath里面?如果是,并且datasource也存在,就自動(dòng)配置一個(gè)jdbctemplate的bean
- thymeleaf是不是在classpath里面?如果是,則自動(dòng)配置thymeleaf的模板解析器、視圖解析器、模板引擎
那個(gè)這個(gè)是怎么實(shí)現(xiàn)的呢?原因就在于它利用了spring的條件化配置,條件化配置允許配置存在于應(yīng)用中,但是在滿足某些特定條件前會(huì)忽略這些配置。
要實(shí)現(xiàn)條件化配置我們要用到@conditional條件化注解。接下來寫個(gè)小例子來感受下@conditional是怎么工作的。
一、@conditional小例子
我們知道在windows下顯示列表的命令是dir,而在linux系統(tǒng)下顯示列表的命令是ls,基于條件配置,我們可以實(shí)現(xiàn)在不同的操作系統(tǒng)下返回不同的值。
1.判斷條件定義
1.)windows下的判定條件
1
2
3
4
5
6
7
8
9
10
|
/** * 實(shí)現(xiàn)spring 的condition接口,并且重寫matches()方法,如果操作系統(tǒng)是windows就返回true * */ public class windowscondition implements condition{ @override public boolean matches(conditioncontext context, annotatedtypemetadata metadata) { return context.getenvironment().getproperty( "os.name" ).contains( "windows" ); } } |
2.)linux下的判定條件
1
2
3
4
5
6
7
8
9
10
|
/** * 實(shí)現(xiàn)spring 的condition接口,并且重寫matches()方法,如果操作系統(tǒng)是linux就返回true * */ public class linuxcondition implements condition{ @override public boolean matches(conditioncontext context, annotatedtypemetadata metadata) { return context.getenvironment().getproperty( "os.name" ).contains( "linux" ); } } |
2.不同系統(tǒng)下的bean的類
1.)接口
1
2
3
|
public interface listservice { public string showlistline(); } |
2.)windows下的bean類
1
2
3
4
5
6
|
public class windowslistservice implements listservice{ @override public string showlistline() { return "dir" ; } } |
3.)linux下的bean的類
1
2
3
4
5
6
|
public class linuxlistservice implements listservice{ @override public string showlistline() { return "ls" ; } } |
3.配置類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@configuration public class conditionconfig { /** * 通過@conditional 注解,符合windows條件就返回windowslistservice實(shí)例 * */ @bean @conditional (windowscondition. class ) public listservice windonwslistservice() { return new windowslistservice(); } /** * 通過@conditional 注解,符合linux條件就返回linuxlistservice實(shí)例 * */ @bean @conditional (linuxcondition. class ) public listservice linuxlistservice() { return new linuxlistservice(); } } |
4.測(cè)試類
1
2
3
4
5
6
7
8
|
public class conditiontest { public static void main(string[] args) { annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(conditionconfig. class ); listservice listservice = context.getbean(listservice. class ); system.out .println(context.getenvironment().getproperty( "os.name" ) + " 系統(tǒng)下的列表命令為: " + listservice.showlistline()); } } |
5.運(yùn)行測(cè)試類,由于我的是windows7 系統(tǒng),因此結(jié)果是
windows 7 系統(tǒng)下的列表命令為: dir
如果你的是linux系統(tǒng),則結(jié)果就會(huì)是
linux 系統(tǒng)下的列表命令為: ls
二、spring boot 的條件化配置
在spring boot項(xiàng)目中會(huì)存在一個(gè)名為spring-boot-autoconfigure的jar包
條件化配置就是在這個(gè)jar里面實(shí)現(xiàn)的,它用到了如下的條件化注解,這些注解都是以@conditional開頭的:
接下來我們看個(gè)源碼的列子:
以jdbctemplateautoconfiguration為例,它里面有這段代碼:
1
2
3
4
5
6
|
@bean @primary @conditionalonmissingbean (jdbcoperations. class ) public jdbctemplate jdbctemplate() { return new jdbctemplate( this .datasource); } |
只有在不存在jdbcoperations(如果查看jdbctemplate的源碼,你會(huì)發(fā)現(xiàn)jdbctemplate類實(shí)現(xiàn)了jdbcoperations接口)實(shí)例的時(shí)候,才會(huì)初始化一個(gè)jdbctemplate 的bean。
基于以上內(nèi)容,我們就可以閱讀自動(dòng)配置相關(guān)的源碼了。
總結(jié)
以上所述是小編給大家介紹的spring boot中@conditional和spring boot的自動(dòng)配置,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!
原文鏈接:http://www.cnblogs.com/sam-uncle/p/9104256.html