Spring - @ComponentScan

@ComponentScan

@ComponentScan是用来扫描组件的,只要用@Service、@Repository、@Controller、@RestController、@Component注解的类都会被Spring实例化到IOC容器中去,和之前使用xml配置文件用到的标签:context:component-scan对应


@Configuration//告诉Spring这是一个配置文件
@ComponentScan(value = "com.booyue.tlh.annotation")//识别:@Service、@Repository、@Controller、@RestController、@Component
public class SpringConfig {

    @Bean(name = "person")//给容器中注册一个bean
    public Person getPerson() {
        return new Person("Lisi", 20);
    }
}

接着在包(子包也可以)com.booyue.tlh.annotation中创建事例Service、dao、controller等等

@RestController
public class PersonController {
}

@Service
public class PersonService {
}

@Repository
public class PersonDao {
}

接下来我们通过Debug就能从beanDefinitionMap中看到我们定义的Service、Controller、Dao等信息

Spring - @ComponentScan_第1张图片

 

@ComponentScan的excludeFilters

当我我们不需要@ComponentScan为我们扫描到特定的组件的时候,这个时候我们就需要选用@ComponentScan的excludeFilters来定义规则。具体的Filter的类型,系统通过枚举类org.springframework.context.annotation.FilterType指定了有:ANNOTATION、ASPECTJ、REGEX、CUSTOM、ASSIGNABLE_TYPE

接下来我们把用@Service注解的来排除掉:

//告诉Spring这是一个配置文件
@Configuration
//识别:@Service、@Repository、@Controller、@RestController、@Component
@ComponentScan(value = "com.booyue.tlh.annotation", excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class})
})
public class SpringConfig {

    @Bean(name = "person")//给容器中注册一个bean
    public Person getPerson() {
        return new Person("Lisi", 20);
    }
}

我们再次通过Debug调试的时候,就在Spring的beanDefinitionMap中找不到personService了,就只能看到personDao和personController

Spring - @ComponentScan_第2张图片

 

@ComponentScan的includeFilters

这里includeFilters和上面的excludeFilters用法一样,只不过这里的意思是只包含的意思。还有一点不同的是,我们在使用includeFilters的是和之前xml的方式一样需要将useDefaultFilters(默认值为true)设置成false,我们的includeFilters才会生效。通过这个配置,你会发现在Spring的IOC容器中就只会出现personService了。(这里我们通过ASSIGNABLE_TYPE又指定了一个PersonController的类型,只要是PersonController类及其子类也会被实例化到Spring的IOC容器中去)

//告诉Spring这是一个配置文件
@Configuration
//识别:@Service、@Repository、@Controller、@RestController、@Component
@ComponentScan(value = "com.booyue.tlh.annotation", includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class}),
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {PersonController.class})
}, useDefaultFilters = false)
public class SpringConfig {

    @Bean(name = "person")//给容器中注册一个bean
    public Person getPerson() {
        return new Person("Lisi", 20);
    }
}

 

@ComponentScan自定义Fileter

我们通过实现TypeFilter 接口就能实现自定义的Filter

public class MyTypeFilter implements TypeFilter {

    /**
     * @param metadataReader:获取到当前正在扫描的类的信息
     * @param metadataReaderFactory:可以获取到其他任何类的信息
     */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        String className = classMetadata.getClassName();
        System.out.println("---->" + className);
        if (className.contains("er"))
            return true;
        return false;
    }
}

将我们自定义的Filter配置到@ComponentScan中就能让我们的Filter生效了

//告诉Spring这是一个配置文件
@Configuration
@ComponentScans({
//        //识别:@Service、@Repository、@Controller、@RestController、@Component
//        @ComponentScan(value = "com.booyue.tlh.annotation", includeFilters = {
//                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class}),
//                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {PersonController.class})
//        }, useDefaultFilters = false),
        @ComponentScan(value = "com.booyue.tlh.annotation", includeFilters = {
                @ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyTypeFilter.class)
        }, useDefaultFilters = false)
})
public class SpringConfig {

    @Bean(name = "person")//给容器中注册一个bean
    public Person getPerson() {
        return new Person("Lisi", 20);
    }
}

 

 

你可能感兴趣的:(Spring,ComponentScan,Fileter,excludeFilters,includeFilters,自定义Filter)