一般情况下,通过ComponentScan注解来配置要扫描的包,默认情况下会自动被扫描进IOC容器的是@Controller、@Service、@Repository、@Component注解的配置类

使用@ComponentScan的示例,其中的value就是指明要扫描的包名

package config;

import bean.HelloWorld;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(value = "包名称")
public class Config {
    @Bean("hello")
    public HelloWorld hello(){
        return new HelloWorld();
    }
}

 

示例:如下指定按照注解的方式,过滤含Controller.class和Service.class注解的类,只扫描Repository注解的类,需要禁用默认的规则!useDefaultFilters = false即可,后面有示例代码

@ComponentScan(value = "bean",
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})},
        includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Repository.class})
        })

完整代码示例:

package config;

import bean.HelloWorld;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

@Configuration
@ComponentScan(value = "bean",
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})},
        includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Repository.class})
        })
public class Config {
    @Bean("hello")
    public HelloWorld hello() {
        return new HelloWorld();
    }
}

如果要禁用默认的扫描规则则加入useDefaultFilters = false。下面的只会扫描bean包下的@Repository注解的类

@ComponentScan(value = "bean",
       includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Repository.class})
        },useDefaultFilters = false)

如果是jdk8支持重复注解@ComponentScan

如果不是则可以通过使用 

@ComponentScans(value={

         @ComponentScan,

         @ComponentScan,

})

@ComponentScan和前面一样使用

扫描包的规则除了注解的方式,有如下几种方式 

/*
FilterType.ANNOTATION     是按照注解的方式 过滤(默认的方式)

FilterType.ASPECTJ        按照ASPECTJ 表达式(一般不会使用)

FilterType.REGEX          按照正则表达式

FilterType.ASSIGNABLE_TYPE 按照指定的类型

FilterType.CUSTOM          按照自定义规则
*/

  如果使用自定义的规则,则需要编写java类并且实现TypeFilter接口的match方法@Filter中的classes指定自定义的实现类

 例如有一个MyFilterType类实现了TypeFilter接口

则如下即可

@ComponentScan(value = "bean",
       includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {MyTypeFilter.class})
        },useDefaultFilters = false)

 

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 MyFilterType 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);
        if (className.contains("Controller")){//扫描包下面的类中 类名包含Controller则匹配成功,同理可以改成其它
            return true;
        }
        return false;
    }
}

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐