组件注册——@ComponentScan注解

@注解用于自动扫描指定包下的所有组件,也可以通过添加属性值来指定扫描规则 。1、@(="包名") , 最简单的使用方法,扫描包名下的所有组件 。
项目结构
类内容,该类是一个配置类,相当于一个xml配置文件 。@( = "com.wyx.")表示会扫描com.wyx.包下的所有组件,并将这些组件添加到IOC容器中 。
package com.wyx.config;import com.wyx.domain.Person;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@Configuration@ComponentScan(basePackages = "com.wyx.controller" )public class MainConfig {@Beanpublic Person person(){return new Person("李思",20);}}
MainTest类的内容 , 这是一个测试类,输出容器中所有的bean,运行程序会发现,容器中有controller包下的bean 。package com.wyx;import com.wyx.config.MainConfig;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class MainTest {public static void main(String[] args){ApplicationContext atcApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);String[] beanDefinitionNames = atcApplicationContext.getBeanDefinitionNames();for(String name:beanDefinitionNames){System.out.println(name);}}}
运行结果
2、 = {@.(type= .***, = ***.class),...},指定扫描规则 , 去除指定注解的组件 。
如源码所示,属性是一个@.注解数组 , 每个@.之间用逗号分隔 。
@.的源码如下图所示 , 有type、、value三个属性

组件注册——@ComponentScan注解

文章插图
如下图所示,先来看type属性,它是类型的,而是一个枚举类型,一种有五个值 。分别是.:指定注解
.:指定类型
.:语法指定,很少使用
.REGEX:使用正则表达式指定
.:自定义规则
属性则是一个运行时类型Class对象 。
实例:项目结构同上MainConfig类代码如下:@ComponentScan.Filter(type= FilterType.ANNOTATION,value = http://www.kingceram.com/post/Repository.class) 去除@Repository注解组件@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,value=Person.class) }) 去除Person类Bean
package com.wyx.config;import com.wyx.domain.Book;import com.wyx.domain.Person;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.Repository;@Configuration@ComponentScan(basePackages = "com.wyx" ,excludeFilters = {@ComponentScan.Filter(type= FilterType.ANNOTATION,value = http://www.kingceram.com/post/Repository.class),@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,value=Person.class)})public class MainConfig {@Beanpublic Person person(){return new Person("李思",20);}@Beanpublic Book book(){return new Book("十万个为什么",160);}}测试类同上面MainTest类
程序运行结果:
组件注册——@ComponentScan注解

文章插图
这里有一个注意点,.只能识别到由注解的普通bean,无法去除通过java配置类注入的bean 。
3、 = {@.(type= .***, = ***.class),...},指定扫描规则,只注入符合注解条件的组件 。
这个与用法相似,但是有一个注意点 , 用这个属性时,需要添加一个属性 。因为默认是注入所有扫描到的组件,所以要将的属性值设置为false , 才能生效 。
类做如下修改
【组件注册——@ComponentScan注解】@Configuration@ComponentScan(basePackages = "com.wyx" ,includeFilters = {@ComponentScan.Filter(type= FilterType.ANNOTATION,value = http://www.kingceram.com/post/Repository.class),@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,value=Person.class)},useDefaultFilters = false)
只扫描注解和类
运行结果:
4、自定义规则,需要编写一个类 , 该类实现了接口的类,下面是我自己定义的类,当该类返回true时,会选中该组件 。接口中有一个抽象方法:match( , y y),当中有两个形参:
MetadataReader metadataReader 读取到当前正在扫描的类信息
MetadataReaderFactory metadataReaderFactory 可以获取到其他任何类的信息MyTypeFilter类代码如下:package com.wyx.config;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 {public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {//当前类的注解信息AnnotationMetadata annotationMetadata = http://www.kingceram.com/post/metadataReader.getAnnotationMetadata();//当前正在扫描的类的信息ClassMetadata classMetadata = metadataReader.getClassMetadata();//当前类的资源,比如类的路径Resource resource = metadataReader.getResource();if(classMetadata.getClassName().contains("Book")) {return true;}return false;}
配置类如下所示
package com.wyx.config;import com.wyx.domain.Book;import com.wyx.domain.Person;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.FilterType;@Configuration@ComponentScan(basePackages = "com.wyx" ,includeFilters = {@ComponentScan.Filter(type=FilterType.CUSTOM,classes = MyTypeFilter.class)},useDefaultFilters = false)public class MainConfig {@Beanpublic Book book(){return new Book("yes",120);}@Beanpublic Person person(){return new Person("张三",12);}}运行结果:(只会通过类名中含有Book的bean)