Python 官方文档:入门教程 => 点击学习
目录@ComponentScan注解的使用一、注解定义二、使用1.环境准备2.excludeFilters的使用3.includeFilters的使用4.自定义过滤规则关于@Comp
@ComponentScan注解的定义如下:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
*.class"
* 使用 includeFilters 和 excludeFilters 会更灵活
*/
String resourcePattern() default ClassPathScanninGCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
boolean useDefaultFilters() default true;
Filter[] includeFilters() default {};
Filter[] excludeFilters() default {};
boolean lazyInit() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({})
@interface Filter {
FilterType type() default FilterType.ANNOTATION;
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String[] pattern() default {};
}
}
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.26.RELEASE</version>
</dependency>
<!-- Https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
创建bean,controller,dao,service层,并在类上加上对应的注解,项目结构如下:
编写测试类,如下:
public class iocTest {
@Test
public void test01() {
//获取Spring的IOC容器
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);
//从容器中获取bean
String[] names= applicationContext.getBeanDefinitionNames();
for(String i:names) {
System.out.println(i);
}
}
}
使用excludeFilters不扫描com.learn包中的Controller、Service注解,如下:
@Configuration
@ComponentScan(basePackages = "com.learn",excludeFilters = {
@Filter(type = FilterType.ANNOTATION,classes = {Controller.class,Service.class})
})
public class SpringConfig {
}
上面使用的excludeFilters用于设置排除的过滤条件,实现Filter接口的type属性用于设置过滤类型,默认值为FilterType.ANNOTATION,提供了这几个过滤类型:
FilterType.ANNOTATION
:按照注解过滤FilterType.ASSIGNABLE_TYPE
:按照给定的类型过滤FilterType.ASPECTJ
:按照ASPECTJ表达式过滤FilterType.REGEX
:按照正则表达式过滤FilterType.CUSTOM
:按照自定义规则过滤classes和value属性为过滤器的参数,必须为class数组,类只能为以下三种类型:
ANNOTATION
参数为注解类,如 Controller.class, Service.class,Repository.classASSIGNABLE_TYPE
参数为类,如 SchoolDao.classCUSTOM
参数为实现 TypeFilter 接口的类 ,如 MyTypeFilter.classincludeFilters属性用于定义扫描过滤条件,满足该条件才进行扫描。用法与excludeFilters一样。
但是因为useDefaultFilters属性默认为true,即使用默认的过滤器,启用对带有@Component,@Repository,@Service,@Controller注释的类的自动检测。会将带有这些注解的类注册为bean装配到IoC容器中。所以使用includeFilters时,需要把useDefaultFilters设置为false,如下:
@Configuration
@ComponentScan(basePackages = "com.learn",includeFilters = {
@Filter(type = FilterType.ANNOTATION,classes = {Controller.class,Service.class})
},useDefaultFilters = false)
public class SpringConfig {
}
结果如下,只扫描了带有Controller,Service注解的自定义的类:
@ComponentScan注解扫描或解析的bean只能是Spring内部所定义的,比如@Component、@Service、@Controller或@Repository。如果要扫描一些自定义的注解,就可以自定义过滤规则来完成这个操作。
自定义一个类MyTypeFilter实现TypeFilter接口,这样这个TypeFilter就扫描所有类并只通过类名包含了controller的类,如下:
public class MyTypeFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
// TODO Auto-generated method stub
//获取当前类注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类的类信息
ClaSSMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前类资源(类的路径)
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
if(className.contains("controller")){
return true;
}
return false;
}
}
在@ComponentScan注解中进行配置,如下:
@Configuration
@ComponentScan(basePackages = "com.learn",includeFilters = {
@Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Person.class}),
@Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class}),
},useDefaultFilters = false)
public class SpringConfig {
}
经过上面的配置,第一个@Filter通过FilterType.ASSIGNABLE_TYPE规定了只扫描Person类型的类,第二个@Filter通过FilterType.CUSTOM自定义过滤规则规定了只扫描类名包含controller的类。结果:
@ComponentScan注解可以扫描 任意 类 或者 注解 中内部类bean;
要想被扫描的前提是内部类标注了@Component及其相关衍生注解、内部类必须是static修饰,否则扫描不到;如果是注解的内部类则只能是public static修饰
//@Configuration
public class ProfileConfig {
@Component("class1")
private static class Class1 {
@Bean
public Class3 class3() {
return new Class3();
}
}
@Component("class2")
static class Class2 {
}
//@Component("class3")
protected static class Class3 {
}
// @Component("class4") //出错
// protected class Class4 {
//
// }
}
--------------------------------------------------------
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
//@Bean
public @interface MyBean {
public static final int age1=3; //常量可以
int age=2;
public abstract String value() default "qwer"; //属性可以
//内部类可以
@Component
@DependsOn("myBean.EventZ") //依赖事件bean的创建,保证该bean在事件bean之后创建
//细节:因为是内部类,所以默认bean的id是类名首字母小写,不是eventZ而是myBean.EventZ
class EventSource {
public EventSource(){
System.out.println("事件源创建了...");
}
}
@Component//("eventZ")
public static class EventZ {
public EventZ(){
System.out.println("事件创建了...");
}
}
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
--结束END--
本文标题: 基于@ComponentScan注解的使用详解
本文链接: https://www.lsjlt.com/news/132673.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0