三、Spring-包掃描註解@ComponentScan

在一個項目開發中,通常會把項目分爲
一、DAO層(數據訪問層):專門負責數據庫交互 CRUD(增查改刪),好比在mysql數據庫裏生成一條訂單數據。java

二、Service層(業務邏輯層) : 負責業務邏輯的處理,好比購買東西的業務,須要調用DAO層的方法扣減商品記錄裏的庫存數量,而後生成一條訂單記錄。mysql

三、Controller層(控制層) : 接收頁面的請求,調用業務邏輯層去處理,將業務邏輯層處理返回的結果返回給頁面。spring

spring中對每一層都提供了相應的註解進行標識:sql

spring還提供了 @Component 組件,沒有明確的角色,只是標明該類要註冊到spring容器中。數據庫

spring可使用 @ComponentScan 註解掃描指定包下標有上面那些註解的類註冊到spring容器中。數組

一、基礎使用app

下面配置類使用了包掃描註解@ComponentScan,並指定了掃描的包名爲com.suzhe.spring.basic.scan, spring啓動的時候就會掃描該包下全部的符合條件的類,並注入到spring容器中。ide

@Configuration  //告訴Spring這是一個配置類
//包掃描:若是沒有配置則默認掃描爲當前類所在包及其子包
@ComponentScan(value = "com.suzhe.spring.basic.scan")
public class ScanConfig {
}

添加幾個類:其中Message1 沒有註解,不符合條件測試

@Controller
public class GreetingController {
}
@Service
public class GreetingService {

}
@Repository
public class GreetingDao {
    public String getMessage(){
        return "welcome";
    }
}
@Component
public class Message {

}
public class Message1 {

}

運行測試.net

@Test
	public void test1(){
		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(ScanConfig.class);
		//獲取容器中全部註冊的bean的name,返回一個數組
		String[] names = app.getBeanDefinitionNames();
		for(String name:names){
			System.out.println(name);
		}
	}

能夠看出spring把指定包下符合條件的類都註冊到了容器中

值得注意的是,這些註解都有一個 value屬性,是指定註冊到spring中實例的name,默認爲 類名首字母小寫。

咱們能夠設置以下

@Service(value = "gs")
public class GreetingService {

}

再次運行測試,能夠看到註冊到spring中bean實例的name變成了gs。

同理,其餘註解也同樣。

 

二、擴展-包含過濾

註解@ComponentScan 還提供includeFilters屬性指定掃描的時候只須要包含哪些組件。

其中Filter有下面幾種過濾類型:

FilterType.ANNOTATION:按照註解
FilterType.ASSIGNABLE_TYPE:按照給定的類型;
FilterType.ASPECTJ:使用ASPECTJ表達式
FilterType.REGEX:使用正則指定
FilterType.CUSTOM:使用自定義規則

示例配置類1

該類配置了FilterType.ANNOTATION和FilterType.ASSIGNABLE_TYPE ,那麼就只有註解爲@Service的類和Message會被註冊到spring容器中。

須要注意的是useDefaultFilters設置爲false。

@Configuration  //告訴Spring這是一個配置類
//包掃描:若是沒有配置則默認掃描爲當前類所在包及其子包
@ComponentScan(value = "com.suzhe.spring.basic.scan",includeFilters ={
        @ComponentScan.Filter(type= FilterType.ANNOTATION, classes={Service.class}),
        @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,classes={Message.class}),
}, useDefaultFilters=false)
public class ScanIncludeConfig {


}

測試運行

@Test
	public void test2(){
		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(ScanIncludeConfig.class);
		String[] names = app.getBeanDefinitionNames();
		for(String name:names){
			System.out.println(name);
		}
	}

從下面的結果能夠看出,只有兩個符合過濾條件的類注入到了spring容器中。

 

同時咱們還能夠自定義過濾器,以下

public class CustomTypeFilter implements TypeFilter{
	private ClassMetadata classMetadata;
	/*
	 * MetadataReader:讀取到當前正在掃描類的信息
	 * MetadataReaderFactory:能夠獲取到其餘任何類信息
	 */
	@Override
	public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {
		//獲取當前類註解的信息
		AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
		//獲取當前正在掃描的類信息
		classMetadata = metadataReader.getClassMetadata();
		//獲取當前類資源(類的路徑)
		Resource resource = metadataReader.getResource();
		String className = classMetadata.getClassName();
		System.out.println("----->"+className);
		if(className.contains("Controller")){//當類名包含Controller字符, 則匹配成功,返回true
			return true;
		}
		return false;
	}

}

經過FilterType.CUSTOM 指定過濾器CustomTypeFilter ,那麼spring就只會註冊符合CustomTypeFilter過濾條件的類。

@Configuration  //告訴Spring這是一個配置類
//包掃描:若是沒有配置則默認掃描爲當前類所在包及其子包
@ComponentScan(value = "com.suzhe.spring.basic.scan",includeFilters ={
        @ComponentScan.Filter(type=FilterType.CUSTOM,classes={CustomTypeFilter.class}),
}, useDefaultFilters=false)
public class ScanIncludeCustomConfig {


}

測試運行

@Test
public void test02(){
   AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(ScanIncludeCustomConfig.class);
   String[] names = app.getBeanDefinitionNames();
   for(String name:names){
      System.out.println(name);
   }
}

能夠看到只有符合條件的GreetingController 被註冊了。

 

同時@ComponentScan還提供了排除的過濾功能:

useDefaultFilters=true excludeFilters = Filter[] :指定掃描的時候按照什麼規則排除哪些組件

includeFilters是包含哪些,excludeFilters是排除哪些,其餘的都同樣,這裏再也不作過多的說明。

相關文章
相關標籤/搜索