在@ComponentScan注解部分我们在使用exclueFilters是说到过FilterType,如下
@ComponentScan(value="com.lhb.bean",excludeFilters = {@ComponentScan.Filter(type= FilterType.ANNOTATION,classes = Repository.class)
意思就是:容器不会将Repository作为注解修饰的类,作为bean放到容器中,也就是使用了Repository注解的类都会排除在外,不放到容器中。
那么本章节,将重点介绍一下这个TypeFilter,他是一个枚举类型,如下:
public enum FilterType {
ANNOTATION, // 通过注解来指定哪些类可以作为bean放到容器中
ASSIGNABLE_TYPE, // 将指定的类,作为bean放到容器中
ASPECTJ,
REGEX,
CUSTOM
}
ANNOTATION的用法开头已经讲过了,下面来看一下剩下几个的用法。
- FilterType.ASSIGNABLE_TYPE
@Configuration // 相当于写了一个spring的xml配置文件 //FilterType.ASSIGNABLE_TYPE:你给我指定一个类型,我就将这个类型的类作为bean放到容器中 @ComponentScan(value="com.lhb.bean",includeFilters = {@ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE,classes = MyService.class)},useDefaultFilters = false) public class MyConfig { }
运行结果如下,我们发现只将指定的MyService作为bean放到容器中了,之前创建的带有@Repository注解的MyDao类并没有作为bean放到容器中。public class AppliactionRunner { public static void main(String[] args) { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class); String[] names = applicationContext.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } } }
所以可以看出:FilterType.ASSIGNABLE_TYPE就是告诉容器,只讲我后面指定的这个类作为bean放到容器中,包括它的子类和实现类。
注意:别忘了要使用includeFilter,必须设置useDefaultFilters=false - FilterType.ASPECTJ
意思就是将满足ASPECTJ表达式的类作为bean放到容器中,但是基本都不会使用这个选项,所以就不介绍了 - FilterType.REGEX
意思就是:将满足正则表达式的类,作为bean放到容器中。
- FilterType.CUSTOM
意思就是:可以指定一个自定义的规则,满足这个规则的类,将作为bean放到容器中。其实就是你自己实现一个TypeFilter接口的类,类中有个方法,容器会把每个类当做参数传到这个方法中,如果传进来的类,满足方法中的规则也就是返回true,这个类将作为bean放到容器中。
例子:将类名含有Dao的类,所谓bean放到容器中
首先:自定义一个TypeFilter的实现类
然后,修改配置:public class MyTypeFilter implements TypeFilter { /**满足下面方法也就是返回true的类,将作为bean放到容器中 * @param metadataReader 读取到的当前正在扫描的类的信息 * @param metadataReaderFactory 可以获取其他任何类型的信息 */ @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //获取当前注解类的信息 AnnotatedTypeMetadata annotatedTypeMetadata = metadataReader.getAnnotationMetadata(); //获取当前正在扫描的类信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); //获取当前类资源(比如:类的路径) Resource resource = metadataReader.getResource(); String className = classMetadata.getClassName(); //System.out.println(className); // 将类名中包含Dao的类,作为bean放到容器中 if(className.contains("Dao")){ return true; } return false; } }
运行的main方法跟之前一样,这里不在给出,然后运行得到结果如下:@Configuration // 相当于写了一个spring的xml配置文件 @ComponentScan(value="com.lhb.bean",includeFilters = {@ComponentScan.Filter(type= FilterType.CUSTOM,classes = MyTypeFilter.class)},useDefaultFilters = false) public class MyConfig { }
可以看到MyDao.class这个类因为满足类名中含有Dao字符串的规则,所以被作为bean放到容器中了。这种方式,跟类上是否有注解没有任何关系了。只要你的类名含有Dao,都会放到容器中,不管类上是否有注解。只有FilterType.ANNOTATION才跟类上的注解有关。