SpringBoot手動(dòng)裝配,自定義Enable模塊
前言
前面我們介紹了簡(jiǎn)單詳細(xì)的SpringBoot自動(dòng)配置原理解析,今天這篇文章主要是介紹下如何是實(shí)現(xiàn)手動(dòng)配置,自定義Enable模塊,
基于注解驅(qū)動(dòng)實(shí)現(xiàn)
基于注解的驅(qū)動(dòng)實(shí)現(xiàn)是最基本的自定義Enable模塊,它是不帶條件的裝配。首先我們來看看如何來實(shí)現(xiàn)!
第一步: 定義好配置類
這里定義了配置類SayHelloWorldConfiguration
public class SayHelloWorldConfiguration {
@Bean
SayHelloWorld sayHelloWorld() {
System.out.println("********加載HelloConfig");
return new SayHelloWorld();
}
}
這里就是實(shí)例化SayHelloWorld類,添加@Bean
注解表明該方法實(shí)例化的對(duì)象會(huì)被加載到IOC容器之中。
第二步:定義EnableXXX注解
這里定義EnableHello注解,并且通過@Import
注解將SayHelloWorldConfiguration配置類導(dǎo)入并加載到IOC容器。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
//引入HelloConfig配置類
@Import({SayHelloWorldConfiguration.class})
public @interface EnableHello {
}
第三步:在SpringBoot的啟動(dòng)類上添加Enable注解
至此基于注解驅(qū)動(dòng)的手動(dòng)配置就好了。啟動(dòng)之后我們就可以拿到實(shí)例化后的SayHelloWorld對(duì)象。但是,他這個(gè)是不能帶任何條件的。
基于選擇器實(shí)現(xiàn)的手動(dòng)配置
與基于注解驅(qū)動(dòng)的不同的是,基于選擇器實(shí)現(xiàn)的手動(dòng)配置需要增加一個(gè)選擇器。步驟如下:
第一步 自定義選擇器,實(shí)現(xiàn)ImportSelector
public class HelloWorldImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//獲取注解上的屬性
Map<String, Object> annotationAttributes = annotationMetadata.getAnnotationAttributes(EnableSelectorHelloWorld.class.getName());
Boolean isLinux = (Boolean) annotationAttributes.get("isLinux");
return new String[]{isLinux ? SayHelloWorldConfiguration.class.getName() : SayHelloWorldConfiguration2.class.getName()};
}
}
這個(gè)選擇器可以根據(jù)注解中傳入的參數(shù),返回不同的配置類,如上,當(dāng)注解中的isLinux為true時(shí),返回的配置類是SayHelloWorldConfiguration,否則,返回的配置類是SayHelloWorldConfiguration2
第二步:定義Enable注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({HelloWorldImportSelector.class})
public @interface EnableSelectorHelloWorld {
boolean isLinux();
}
這里引入的是我們前面定義的選擇器類。
后面的步驟跟基于注解驅(qū)動(dòng)實(shí)現(xiàn)一致,在此就不在贅述了。
條件裝配
如果某些配置類需要滿足一定的條件才能啟動(dòng),該如何實(shí)現(xiàn)呢?這就需要用到條件裝配了。條件裝配的配置步驟如下:
第一步:定義Condition的實(shí)現(xiàn)類
public class OnSystemPropertyCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//獲取注解屬性
Map<String, Object> attrs = annotatedTypeMetadata.getAnnotationAttributes(ConditionalOnSystemProperty.class.getName());
//獲取系統(tǒng)值
String system = String.valueOf(attrs.get("value"));
String currentOs = System.getProperty("os.name");
boolean result = currentOs.contains(system);
System.out.println("********currentOs=" + currentOs + "匹配結(jié)果是=" + result);
return result;
}
}
這里的代碼也比較簡(jiǎn)單,就是根據(jù)ConditionalOnSystemProperty注解傳入的value值,是否包含在當(dāng)前系統(tǒng)的系統(tǒng)名中,如果是的話則返回true。否則,返回false。返回true的話,則會(huì)加載配置類中通過@Bean
定義的對(duì)象。
第二步:定義配置類
public class SayHelloWorldConfiguration2 {
/**
* @return
*/
@ConditionalOnSystemProperty(value = "Windows")
@Bean
SayHelloWorld sayHelloWorld() {
System.out.println("*********開始裝配SayHelloWorld");
return new SayHelloWorld();
}
}
定義Enable注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({SayHelloWorldConfiguration2.class})
public @interface EnableConditionHelloWorld {
}
總結(jié)
手動(dòng)裝配其實(shí)也是很簡(jiǎn)單的。上面就簡(jiǎn)單的示例了三種情況下的裝配。希望對(duì)讀者朋友們有所幫助。
源碼下載
源碼下載
作者:碼農(nóng)飛哥
微信公眾號(hào):碼農(nóng)飛哥