SpringBoot高級-自動配置之Enable*注解原理


前言:SpringBoot中提供了很多Enable開頭的注解,這些注解都是用於動態啟用某些功能的。其底層原理是使用@Import注解導入一些配置類,實現Bean的動態加載。所以,SpringBoot的自動配置,就是依賴於各種Enable開頭的注解,而Enable開頭的注解,又依賴於@Import注解實現的。

首先,我們來看SpringBoot引導類上的注解@SpringBootApplication,進一步了解引導類中使用的Enable開頭的注解。

@SpringBootApplication
public class SpringbootConfigApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootConfigApplication.class, args);
    }

}

進入@SpringBootApplication注解中,可以看到,除了三個元注解(元注解這里不解釋了,固定用法,所有的注解都包含這三個注解),主要起作用的其它注解,分別解釋。

一、@Inherited注解:這個注解的作用可以自己看,講的很詳細,也有示例。鏈接:https://www.jianshu.com/p/7f54e7250be3 ,主要作用是
①、類繼承關系中@Inherited的作用:類繼承關系中,子類會繼承父類使用的注解中被@Inherited修飾的注解

②、接口繼承關系中@Inherited的作用:接口繼承關系中,子接口不會繼承父接口中的任何注解,不管父接口中使用的注解有沒有被@Inherited修飾

③、類實現接口關系中@Inherited的作用:類實現接口時不會繼承任何接口中定義的注解

二、@SpringBootConfiguration注解的作用,先進入該注解中,發現該注解就是聲明一個配置類,因此,在SpringBoot引導類中,我們也可以定義Bean。

三、@EnableAutoConfiguration注解,進入該注解中,可以發現,其最終是使用了@Import注解,導入一些配置

四、@ComponentScan注解作用:組件掃描。掃描范圍:當前引導類所在包及其子包。

綜上,@SpringBootApplication注解,依賴的最重要注解就是@EnableAutoConfiguration,及間接依賴的@Import注解。

下面我們做一個示例:驗證SpringBoot工程能否直接獲取jar包中定義的Bean

一、首先,我們新建一個SpringBoot工程springboot-enable,獲取user的Bean

@SpringBootApplication
public class SpringbootEnableApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

        Object user = context.getBean("user");
        System.out.println(user);
    }
}

二、再新建一個SpringBoot工程springboot-enable-user,定義User實體類和User配置類
User實體類

/**
 * @description:user實體類
 * @date: 2020/10/10 10:29
 * @author: winson
 */
public class User {
}

User配置類

/**
 * @description:User配置類
 * @date: 2020/10/10 10:29
 * @author: winson
 */
@Configuration
public class UserConfig {
    @Bean
    public User user() {
        return new User();
    }
}

三、在springboot-enable工程中,導入springboot-enable-user工程的依賴

<dependency>
    <groupId>com.winson</groupId>
    <artifactId>springboot-enable-user</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

四、啟動程序,測試user是否注入到了IOC容器中。

結論:SpringBoot工程不能直接獲取jar包中定義的Bean

接着上述結果,說明為什么不能直接獲取jar包中定義的Bean,這跟引導類@SpringBootApplication注解上的@ComponentScan注解有關系,上述提到了該注解,其掃描范圍為引導類所在的包及其子包,而上述測試用的User配置類並不在這個范圍內,所以無法獲取到。

引導類所在的包為:com.winson.springbootenable
User配置類所在的包為:com.winson.config

下面就上述問題,給出答案,實現SpringBoot工程可以獲取jar包中定義的Bean

方法一、使用@ComponentScan注解,將User配置類所在包,加入掃描范圍
修改引導類,加入@ComponentScan注解,將User配置類所在包,加入掃描范圍

@SpringBootApplication
@ComponentScan("com.winson.config")
public class SpringbootEnableApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

        Object user = context.getBean("user");
        System.out.println(user);
    }

}

測試結果:可以發現這時可以獲取user的Bean。

方法二、使用@Import注解,將User配置類導入到引導類中

@SpringBootApplication
@Import(UserConfig.class)
public class SpringbootEnableApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

        Object user = context.getBean("user");
        System.out.println(user);
    }
}

測試結果:也可以獲取user的Bean。

方法三、對@Import注解進行封裝

一、新建一個注解類@EnableUser,使用@Import導入User配置類UserConfig

/**
 * @description:封裝@Import注解
 * @date: 2020/10/10 11:20
 * @author: winson
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(UserConfig.class)
public @interface EnableUser {
}

二、在引導類中,使用@EnableUser注解

@SpringBootApplication
@EnableUser
public class SpringbootEnableApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);

        Object user = context.getBean("user");
        System.out.println(user);
    }
}

三、啟動程序,測試結果:也可以獲取user的Bean。

小結:SpringBoot自動配置依賴於各種@Enable開頭的注解,@Enable開頭的注解,底層還是通過@Import注解實現的,所以自動配置的最核心就是使用了@Import注解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM