springboot系列 @ComponentScan和@EnableAutoConfiguration的區別

研究springboot源碼,在網上看相關博客的時候對@ComponentScan和@EnableAutoConfiguration兩者之間的作用沒有做過多的區分,導致我覺得他們兩者都有掃描相關組建然後將符合要求的放入到ioc容器中。所以我就佔牛角尖了,單獨研究了一下他們的不同點。
@ComponentScan和@EnableAutoConfiguration都是包含在@SpringBootApplication中的,也是@SpringBootApplication中比較重要的註解。
@ComponentScan和@EnableAutoConfiguration的相同點
兩者都可以將帶有@Component,@Service等註解的對象加入到ioc容器中。

@ComponentScan和@EnableAutoConfiguration的不同點
1.兩者雖然都能將帶有註解的對象放入ioc容器中,但是它們掃描的範圍是不一樣的。@ComponentScan掃描的範圍默認是它所在的包以及子包中所有帶有註解的對象,@EnableAutoConfiguration掃描的範圍默認是它所在類。
2.它們作用的對象不一樣,@EnableAutoConfiguration除了掃描本類帶有的註解外,還會 藉助@Import的支持,收集和註冊依賴包中相關的bean定義,將這些bean注入到ioc容器中,在springboot中注入的bean有兩部分組成,一部分是自己在代碼中寫的標註有@Controller,@service,@Respority等註解的業務bean,這一部分bean就由@ComponentScan將它們加入到ioc容器中,還有一部分是springboot自帶的相關bean,可以將這部分bean看成是工具bean,這部分bean就是由@EnableAutoConfiguration負責加入到容器中。
3.@EnableAutoConfiguration可以單獨啓動springboot項目,而@ComponentScan是不能的。

下面用代碼來驗證第一點和第三點


第一種情況,驗證@EnableAutoConfiguration的掃描範圍

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import study.springboot.component.subPackage.Food;

/**
 * @Author wangbiao
 * @Date 2019-09-01 09:49
 * @Decripition TODO
 **/
@RestController
@EnableAutoConfiguration
public class DogController {


    @RequestMapping(value = "showDog",name = "測試@Component,@EnableAutoConfiguration掃描範圍")
    public String showDog(){
        return "中華田園犬";
    }


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


}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import study.springboot.component.subPackage.Food;

/**
 * @Author wangbiao
 * @Date 2019-09-01 10:00
 * @Decripition TODO
 **/
@RestController
public class CatController {
    @RequestMapping(value = "showCat",name = "測試@Component,@EnableAutoConfiguration掃描範圍")
    public String showCat(){
        return "波斯貓";
    }
}

然後用http://localhost:8080/showDog來訪問,得到的結果是:

http://localhost:8080/showCat訪問,得到的結果是:

得到的結果是@EnableAutoConfiguration不能將同一個包下帶有註解的對象加入到ioc容器中

下面驗證@EnableAutoConfiguration能否將子包中的註解對象加入到ioc容器中

import org.springframework.stereotype.Component;

/**
 * @Author wangbiao
 * @Date 2019-09-19 10:47
 * @Decripition TODO
 **/
@Component
public class Food {
    private String foodname="狗糧,貓糧";

    public String getFoodname() {
        return foodname;
    }

    public void setFoodname(String foodname) {
        this.foodname = foodname;
    }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import study.springboot.component.subPackage.Food;

/**
 * @Author wangbiao
 * @Date 2019-09-01 09:49
 * @Decripition TODO
 **/
@RestController
@EnableAutoConfiguration
public class DogController {

    @Autowired
    private Food food;
    @RequestMapping(value = "showDog",name = "測試@Component,@EnableAutoConfiguration掃描範圍")
    public String showDog(){
        return "中華田園犬"+food.getFoodname();
    }


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


}

啓動就報錯了:

可以看到@EnableAutoConfiguration是不能將子包中的註解對象加入到ioc容器中。
 

第二種情況,驗證@Component的掃描範圍
在@EnableAutoConfiguration註解上面加上@Component

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import study.springboot.component.subPackage.Food;

/**
 * @Author wangbiao
 * @Date 2019-09-01 09:49
 * @Decripition TODO
 **/
@ComponentScan
@RestController
@EnableAutoConfiguration
public class DogController {

    @Autowired
    private Food food;
    @RequestMapping(value = "showDog",name = "測試@Component,@EnableAutoConfiguration掃描範圍")
    public String showDog(){
        return "中華田園犬"+food.getFoodname();
    }


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


}

http://localhost:8080/showDog訪問,結果是下面的頁面,可以看出Food這個對象是被引進來了的

再用http://localhost:8080/showCat訪問頁面,得到的結果是下面的頁面,可以看出CatController是被加入到容器中的。所以驗證了第一點,@ComponentScan掃描的範圍默認是它所在的包以及子包中所有帶有註解的對象,@EnableAutoConfiguration掃描的範圍默認是它所在類。
感謝這篇博客提供的參考:https://blog.csdn.net/qq_39404626/article/details/83995870

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章