spring註解 ComponentScan、自定義型別過濾器
阿新 • • 發佈:2019-02-11
@ComponentScan註解,掃描哪些包下,將掃描到的包下的元件加入到容器中,這是一個常見的用法,如@ComponentScan(value = "me.xf"),對掃描到的包下的元件,處理哪些元件可以加入到容器中,哪些元件型別的,不可以加入到容器中,這裡引入了兩個ComponentScan的引數:excludeFilters和includeFilters。
excludeFilters,在掃描到的包下,把哪些給排除掉。excludeFilters 是一個 ComponentScan.Filter[],Filter也是一個註解,接收的引數為要過濾的型別,要過濾的類型別。在Filter中,預設是過濾註解型別,可以改變FilterType的值,來更改過濾的型別,
@Retention(RetentionPolicy.RUNTIME) @Target({}) public @interface Filter { FilterType type() default FilterType.ANNOTATION; @AliasFor("classes") Class<?>[] value() default {}; @AliasFor("value") Class<?>[] classes() default {}; String[] pattern() default {}; }
FilterType有以下幾個值:
public enum FilterType {
ANNOTATION,
ASSIGNABLE_TYPE,
ASPECTJ,
REGEX,
CUSTOM;
private FilterType() {
}
}
分別是按照註解型別、按照給定的型別、按照Aspectj型別、按照正則表示式以及自定義型別,常用的就是按照註解型別和自定義型別來進行過濾。
使用自定義型別過濾,建立一個類,實現TypeFilter介面,複寫match方法,在match方法中,可以拿到類的資訊,從而定製自己的過濾規則:
public class MyTypeFilter implements TypeFilter {
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//獲得當前正在掃描的類的註解資訊
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//獲得當前正在掃描的類的資源資訊
Resource resource = metadataReader.getResource();
//獲得當前正在掃描的類的類資訊
ClassMetadata classMetadata = metadataReader.getClassMetadata();
String name = classMetadata.getClassName();
System.out.println("掃描的類-->" + name);
if(name.contains("Service")){
System.out.println("匹配成功的類-->" + name);
return true;
}
return false;
}
}
includeFilters和excludeFilters類似,只是作用和其相反,是將哪些元件給加入進來,區別在於,要多新增一個 useDefaultFilters = false 的引數。
在配置類中,填寫好相應的引數即可使其生效
//配置類
@Configuration
@ComponentScan(value = "me.xf" , //掃描哪些包下的元件
// excludeFilters = { //在掃描的包下,排除哪些
// @ComponentScan.Filter(type = FilterType.ANNOTATION , //過濾型別,註解型別
// classes = { //確定過濾的類
// Repository.class
// }
// )
// },
// includeFilters = { //在掃描的包下,包含哪些
// @ComponentScan.Filter(type = FilterType.ANNOTATION, //過濾型別
// classes = { //確定過濾的類
// Controller.class
// }
// )
// }
includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM, //過濾型別,自定義型別
classes = { //自定義的類,該類實現TypeFilter介面,複寫match方法,在方法中定義過濾的規則
MyTypeFilter.class
}
)
}
,useDefaultFilters = false //使用includeFilters時,要將useDefaultFilters設定為false
)
public class MyConfig {
static {
System.out.println("配置類載入...");
}
@Bean("person") //預設為方法名小寫,返回的bean的id
public Person getPerson(){
System.out.println("向容器中新增person");
return new Person("張三",20);
}
}
//測試類
public class AnnotationTest {
@Test
public void testComponentScan(){
System.out.println("======測試類開始======");
ApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
System.out.println("======IOC容器建立完成======");
String[] definitionNames = ctx.getBeanDefinitionNames();
for (String name : definitionNames){
System.out.println("bean 的定義名是:" + name);
}
}
}
測試輸出: