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)飛哥