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