@CompentScan的作用就是告诉spring ioc哪些哪些包需要被扫描到。
1,basePackages 配置哪些包下的类可以被扫描到。
@Configuration
@ComponentScan(basePackages = {"com.tuling.testcompentscan.controller","com.tuling.testcompentscan.dao"})
public class MainConfig {
}
public class MainClass {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinationNames = ctx.getBeanDefinitionNames();
for (String name:beanDefinationNames) {
System.out.println("bean的定义信息:"+name);
}
}
}
因为只配置了扫描controller和dao包,所以只有controller和dao的包下面的配置了@Controller, @Service, @Repository, @Component被扫描到了.
其实@Controller, @Service, @Repository中都包含了@Component注解, 其本质就时扫描有@Component注解的类。
结果如下:
FilterType的种类介绍:
a)注解形式的FilterType.ANNOTATION -- 控制:@Controller @Service @Repository @Component被忽略或加入
b)指定类型的 FilterType.ASSIGNABLE_TYPE -- 指定某些类会被忽略或加入,Allen.class
c)自定义的 FilterType.CUSTOM -- 自定义一个类用来来处理ignore的规则或加入规则。
其他的类型用得不多先忽略:
2, FilterType 使用
excludeFilters -- 去掉一些在basepackage中配置了@Controller @Service @Repository @Component的类,可以选择一下方式进行过滤:
1. 将一个包下面的所有包含@Controller注解的类加入:
@Configuration
@ComponentScan(basePackages = {"com.tuling.testcompentscan"})
public class MainConfig {
}
2. FilterType.ANNOTATION,将特定的注解过滤掉。
过滤Controller类型的注解:
@Configuration
@ComponentScan(basePackages = {"com.tuling.testcompentscan"}
,excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class})
}
)
public class MainConfig {
}
package com.tuling.testcompentscan.controller;
import org.springframework.stereotype.Controller;
@Controller
public class TulingController {
}
3. 过滤特定的类,指定类型的 FilterType.ASSIGNABLE_TYPE
@Configuration
@ComponentScan(basePackages = {"com.tuling.testcompentscan"}
,excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class})
,@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {TulingService.class})
}
)
public class MainConfig {
}
4. FilterType.CUSTOM自定义过滤规则
@Configuration
@ComponentScan(basePackages = {"com.tuling.testcompentscan"}
,excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class})
,@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {TulingService.class})
,@ComponentScan.Filter(type = FilterType.CUSTOM, value = TulingFilterType.class)
}
)
public class MainConfig {
}
自定义 TulingFilterType,需要继承TypeFilter 类:
package com.tuling.testcompentscan.filtertype;
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 TulingFilterType implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类的注解源信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前类的资源信息
Resource resource = metadataReader.getResource();
//获取当前类的class的源信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
System.out.println("类的路径:"+classMetadata.getClassName());
if(classMetadata.getClassName().contains("dao")) {
return true;
}
return false;
}
}
includeFilters -- 可以将一些在basePackages包下面的,没有加@Component,@Controller @Service @Repository 的类加到IOC容器管理中。
useDefaultFilters = false , useDefaultFilters默认时true 会把basePackages下所有包含@Component,@Controller @Service @Repository的都加到IOC容器中。
includeFilters 要起作用需要把DefaultFilters关掉。useDefaultFilters = false 。
如下,将所有的service注解和controller注解已经自定下的dao都加进来。
5. includeFilters
package com.tuling.testcompentscan.config;
@Configuration
@ComponentScan(basePackages = {"com.tuling.testcompentscan"},includeFilters = {
@ComponentScan.Filter(type=FilterType.ANNOTATION,value= {Controller.class, Service.class})
,@ComponentScan.Filter(type = FilterType.CUSTOM,value = TulingFilterType.class)
},useDefaultFilters = false)
@ComponentScan(basePackages ={"com.tuling.testcompentscan"} )
public class MainConfig {
}
package com.tuling.testcompentscan.dao;
import org.springframework.stereotype.Repository;
@Repository
public class TulingDao {
}
6.Filter 不会影响到@Bean
Filter 只会对@Component ,@Controller ,@Service ,@Repository起作用,不会对@Bean起作用。
package com.tuling.testcompentscan.config;
@Configuration
@ComponentScan(basePackages = {"com.tuling.testcompentscan"},useDefaultFilters = false)
public class MainConfig {
@Bean
public BaiduCom getBaiduDao(){
return new BaiduCom();
}
}