1. @ComponentScan 掃描規則
1.1 指定要掃描的包
- 1 新建配置類Cap2MainConfig,
@ComponentScan(value = "com.zz.cap2")
public class Cap2MainConfig {
}
@ComponentScan(value = “com.zz.cap2”)表示掃描此目錄下的包。
- 2 在com.zz.cap2目錄下新建要掃描的類
OrderController
@Controller
public class OrderController {
}
OrderService
@Service
public class OrderService {
}
OrderDao
@Repository
public class OrderDao {
}
- 3 新建測試類Cap2Test
public class Cap2Test {
@Test
public void test1() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Cap2MainConfig.class);
//從容器獲取bean定義的名稱
String[] names = context.getBeanDefinitionNames();
for( String name : names) {
System.out.println(name);
}
}
}
結果:
使用 ApplicationContext 的 getBeanDefinitionNames() 方法獲取已經註冊到容器中的 bean 的名稱。
1.2 定製包掃描的過濾規則
1.2.1 excludeFilters 和 includeFilters 的使用
1.使用 excludeFilters 來按照規則排除某些包的掃描
修改配置類:
@ComponentScan(value = "com.zz.cap2", excludeFilters = {@Filter(type = FilterType.ANNOTATION, value = Controller.class)})
public class Cap2MainConfig {
}
excludeFilters 的參數是一個 Filter[] 數組,然後指定 FilterType 的類型爲 ANNOTATION,也就是通過註解來過濾,最後的 value 則是Controller 註解類。配置之後,在 spring 掃描的時候,就會跳過 com.zz.cap2 包下,所有被 @Controller 註解標註的類。
結果:
orderController沒有打印出來,排除成功
2.使用 includeFilters 來按照規則只包含某些包的掃描
修改配置類:
@ComponentScan(value = "com.zz.cap2", includeFilters = {@Filter(type = FilterType.ANNOTATION, value = Controller.class)})
public class Cap2MainConfig {
}
配置裏面,應該是隻包含 @Controller 註解的類纔會被註冊到容器中,爲什麼 @Service 註解的類也被註冊了呢?這裏涉及到 @ComponentScan 的一個 useDefaultFilters 屬性的用法,該屬性默認值爲 true,也就是說 spring 默認會自動發現被 @Component、@Repository、@Service 和 @Controller 標註的類,並註冊進容器中。要達到只包含某些包的掃描效果,就必須將這個默認行爲給禁用掉(在 @ComponentScan 中將 useDefaultFilters 設爲 false 即可)。
設置useDefaultFilters 爲false
@ComponentScan(value = "com.zz.cap2", includeFilters = {@Filter(type = FilterType.ANNOTATION, value = Controller.class)}, useDefaultFilters = false)
public class Cap2MainConfig {
}
結果
1.2.2 添加自定義過濾規則
在前面使用過 @Filter 註解,裏面的 type 屬性是一個 FilterType 的枚舉類型:
public enum FilterType {
ANNOTATION, //按照註解過濾
ASSIGNABLE_TYPE, //按照給定的類型
ASPECTJ, //使用ASPECTJ表達式
REGEX, //正則
CUSTOM //自定義規則
}
使用 CUSTOM 類型,就可以實現自定義過濾規則。
- 首先創建一個實現 TypeFilter 接口的 CustomTypeFilter 類,並實現其 match 方法。
public class CustomTypeFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
// 獲取當前掃描到的類的註解元數據
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
// 獲取當前掃描到的類的元數據
ClassMetadata classMetadata = metadataReader.getClassMetadata();
// 獲取當前掃描到的類的資源信息
Resource resource = metadataReader.getResource();
if (classMetadata.getClassName().contains("vice")) {
return true;
}
return false;
}
}
這裏簡單對掃描到的類名進行判斷,如果類名包含”vice“的就符合條件,也就會注入到容器中。
- 對 Cap2MainConfig進行修改,指定過濾類型爲 Custom 類型,並指定 value 爲 CustomTypeFilter.class。
@ComponentScan(value = "com.zz.cap2", includeFilters = {@Filter(type = FilterType.CUSTOM, value = CustomTypeFilter.class)}, useDefaultFilters = false)
public class Cap2MainConfig {
}
運行結果: