02、Spring常用註解一@ComponentScan

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 {
}

運行結果:
在這裏插入圖片描述

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