spring boot 神奇的自動配置,主要依靠大量的條件注解來使用配置自動化。
根據滿足某一個特定條件創建一個特定的bean。比如說,在某些系統變量下創建bean,或者只有在某個bean創建后才去創建另外一個bean. 就是根據條件來控制bean的創建行為,可以利用該特性來進行一些自動配置。
一、常用的條件注解
- @conditional 依賴的條件
- @conditionalonbean 在某個bean存在的條件下
- @conditionalonmissingbean 在某個bean不存在的條件下
- @conditionalonclass 在某個class存在的條件下
- @conditionalonmissingclass 在某個class不存在的條件下
比較常見的是這些注解,還有其它的比如 @conditionalonwebapplication,@conditionalonproperty 等,可舉一反三
二、特別說明 @conditional 注解
1
2
3
4
5
6
7
8
9
10
11
12
|
@target ({elementtype.type, elementtype.method}) @retention (retentionpolicy.runtime) @documented public @interface conditional { /** * all {@link condition conditions} that must {@linkplain condition#matches match} * in order for the component to be registered. */ class <? extends condition>[] value(); } |
使用@conditional注解,對象需要實現condition接口,condition 接口是一個函數式接口
1
2
3
4
5
|
@functionalinterface public interface condition { boolean matches(conditioncontext context, annotatedtypemetadata metadata); } |
三、條件注解示例
示例場景:項目中動態的配置mysql或者oracle數據源
1. 定義配置文件
1
|
db-type=oracle |
2. 定義condition類
mysqlcondition.java
1
2
3
4
5
6
7
|
public class mysqlcondition implements condition { @override public boolean matches(conditioncontext context, annotatedtypemetadata metadata) { return "mysql" .equals(context.getenvironment().getproperty( "db-type" )); } } |
oraclecondition.java
1
2
3
4
5
6
7
|
public class oraclecondition implements condition { @override public boolean matches(conditioncontext context, annotatedtypemetadata metadata) { return "oracle" .equals(context.getenvironment().getproperty( "db-type" )); } } |
獲取配置文件db-type的值
3. jdbcfactory接口
1
2
3
4
|
public interface jdbcfactory { void create(); } |
4. 默認的mysql和oracle實現
mysql
1
2
3
4
5
6
7
8
9
10
11
|
@conditionalonmissingbean (value = jdbcfactory. class , ignored = mysqldefaultfactory. class ) @conditional (mysqlcondition. class ) @component public class mysqldefaultfactory implements jdbcfactory { @override public void create() { system.out.println( "default mysql create .." ); } } |
oracle
1
2
3
4
5
6
7
8
9
10
|
@conditionalonmissingbean (value = jdbcfactory. class , ignored = oracledefaultfactory. class ) @conditional (oraclecondition. class ) @component public class oracledefaultfactory implements jdbcfactory { @override public void create() { system.out.println( "default oracle create.." ); } } |
5. 測試默認實現方式
1
2
3
4
5
6
7
|
@resource private jdbcfactory jdbcfactory; @test public void conditiononmissbean() { jdbcfactory.create(); } |
結果:default mysql create ..
6. 自定義實現方式
1
2
3
4
5
6
7
8
|
@component public class mysqlfactory implements jdbcfactory { @override public void create() { system.out.println( "mysql 。。 create" ); } } |
7. 測試
1
2
3
4
5
6
7
|
@resource private jdbcfactory jdbcfactory; @test public void conditiononmissbean() { jdbcfactory.create(); } |
結果:mysql 。。 create
8.解析
當環境中不存在 jdbcfactory 的bean時則使用默認的實現的方式,如例:沒有自定義實現時,則默認使用mysqldefaultfactory。這在自動化配置中會經常用到。比如redistemplate 的默認實現
四、github源碼
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://juejin.im/post/5c6c2189e51d45713911466d