组件注册——@ComponentScan注解

2023-12-24 23:50

本文主要是介绍组件注册——@ComponentScan注解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

@ComponentScan注解用于自动扫描指定包下的所有组件,也可以通过添加属性值来指定扫描规则。

1、@ComponentScan(basePackages="包名"),最简单的使用方法,扫描包名下的所有组件。

项目结构

 

MainConfig类内容,该类是一个配置类,相当于一个xml配置文件。@ComponentScan(basePackages = "com.wyx.controller")表示会扫描com.wyx.controller包下的所有组件,并将这些组件添加到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、excludeFilters = {@ComponentScan.Filter(type= FilterType.***,classes = ***.class),...},指定扫描规则,去除指定注解的组件。

如源码所示,excludeFilters属性是一个@ComponentScan.Filter注解数组,每个@ComponentScan.Filter之间用逗号分隔。

@ComponentScan.Filter的源码如下图所示,有type、classes、value三个属性

如下图所示,先来看type属性,它是FilterType类型的,而FilterType是一个枚举类型,一种有五个值。分别是FitlerType.ANNOTATION:指定注解

FilterType.ASSIGNABLE_TYPE:指定类型

FilterType.ASPECTJ:Aspectj语法指定,很少使用

FilterType.REGEX:使用正则表达式指定

FilterType.CUSTOM:自定义规则

classes属性则是一个运行时类型Class对象。

实例:项目结构同上
MainConfig类代码如下:@ComponentScan.Filter(type= FilterType.ANNOTATION,value = 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 = 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类

程序运行结果:

这里有一个注意点,FilterType.ASSIGNABLE_TYPE只能识别到由Component注解的普通bean,无法去除通过java配置类注入的bean。

3、includeFilters = {@ComponentScan.Filter(type= FilterType.***,classes = ***.class),...},指定扫描规则,只注入符合注解条件的组件。

这个与excludeFilters用法相似,但是有一个注意点,用这个属性时,需要添加一个属性。因为spring默认是注入所有扫描到的组件,所以要将useDefaultFilters 的属性值设置为false,includeFilters才能生效。

MainConfig类做如下修改

@Configuration
@ComponentScan(basePackages = "com.wyx" ,includeFilters = {@ComponentScan.Filter(type= FilterType.ANNOTATION,value = Repository.class),@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,value=Person.class)
},useDefaultFilters = false)

只扫描Reposity注解和Person类

运行结果:

4、自定义规则,需要编写一个类,该类实现了TypeFilter接口的类,下面是我自己定义的MyTypeFilter类,当该类返回true时,会选中该组件。TypeFilter接口中有一个抽象方法:match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory),当中有两个形参:

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 = 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)

 

 

 

 

 

这篇关于组件注册——@ComponentScan注解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/533567

相关文章

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

Go路由注册方法详解

《Go路由注册方法详解》Go语言中,http.NewServeMux()和http.HandleFunc()是两种不同的路由注册方式,前者创建独立的ServeMux实例,适合模块化和分层路由,灵活性高... 目录Go路由注册方法1. 路由注册的方式2. 路由器的独立性3. 灵活性4. 启动服务器的方式5.

Spring排序机制之接口与注解的使用方法

《Spring排序机制之接口与注解的使用方法》本文介绍了Spring中多种排序机制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了详细示例... 目录一、Spring 排序的需求场景二、Spring 中的排序机制1、Ordered 接口2、Pri

Idea实现接口的方法上无法添加@Override注解的解决方案

《Idea实现接口的方法上无法添加@Override注解的解决方案》文章介绍了在IDEA中实现接口方法时无法添加@Override注解的问题及其解决方法,主要步骤包括更改项目结构中的Languagel... 目录Idea实现接China编程口的方法上无法添加@javascriptOverride注解错误原因解决方

Java中基于注解的代码生成工具MapStruct映射使用详解

《Java中基于注解的代码生成工具MapStruct映射使用详解》MapStruct作为一个基于注解的代码生成工具,为我们提供了一种更加优雅、高效的解决方案,本文主要为大家介绍了它的具体使用,感兴趣... 目录介绍优缺点优点缺点核心注解及详细使用语法说明@Mapper@Mapping@Mappings@Co

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

四种Flutter子页面向父组件传递数据的方法介绍

《四种Flutter子页面向父组件传递数据的方法介绍》在Flutter中,如果父组件需要调用子组件的方法,可以通过常用的四种方式实现,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录方法 1:使用 GlobalKey 和 State 调用子组件方法方法 2:通过回调函数(Callb

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

关于@MapperScan和@ComponentScan的使用问题

《关于@MapperScan和@ComponentScan的使用问题》文章介绍了在使用`@MapperScan`和`@ComponentScan`时可能会遇到的包扫描冲突问题,并提供了解决方法,同时,... 目录@MapperScan和@ComponentScan的使用问题报错如下原因解决办法课外拓展总结@

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言