天天看點

元件注冊@ComponentScan的自動掃描和指定掃描規則

掃描元件@ComponentScan可以自動掃描包以内的含有@Service,@Controller,@Repository,@Component的元件到IOC容器裡面去

@ComponentScan有幾個重要的參數

1.value:填寫要掃描的包(會級聯掃描内部所有子包)

2.excludeFilters(排除掃描元件的規則)

裡面裝的是Filter的數組

Filter有2個屬性:

①type:type是枚舉類,裡面有以下幾種屬性:

ANNOTATION, 注解,

ASSIGNABLE_TYPE, ANNOTATION:指定的類型,按照給定的類型,不管是子類還是實作類

ASPECTJ, 按照Aspectj的表達式,基本上不會用到按照

REGEX, 按照正規表達式

CUSTOM 自定義規則

②value(或者classes): 類類型的數組

按照前面的type定義的規則來找到對應的類進行排除

3.includeFilters,它的屬性和excludeFilters是一樣的,不同的是,它需要關閉ComponentScan裡面的屬性(useDefaultFilters = false)

示例代碼:

ANNOTATION:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

import java.util.ArrayList;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;
@ComponentScan(value = "com.debuggg",excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}),
},useDefaultFilters = false)
           

ASSIGNABLE_TYPE:指定的類及其所有子類,實作類掃描

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

import java.util.ArrayList;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;
@ComponentScan(value = "com.debuggg",excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {UserService.class})
},useDefaultFilters = false)
public class TransferQueueTest {
           

CUSTOM: 自定義掃描規則

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;

import java.util.ArrayList;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;
@ComponentScan(value = "com.debuggg",excludeFilters = {
        @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
},useDefaultFilters = false)
public class TransferQueueTest {
           

MyTypeFilter.java

package com.debuggg.test1.main3;

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

public class MyTypeFilter implements TypeFilter {
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //擷取目前類注解的資訊
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //擷取目前正在掃描的類的資訊
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        //擷取目前類資源(類的路徑)
        Resource resource = metadataReader.getResource();

        String className = classMetadata.getClassName();

        System.out.println("----> " + className);
        //如果掃描到的類裡面包含er就加入到ioc容器裡面
        if(className.contains("er")){
            return true;
        }
        return false;
    }
}