Spring注解详解:@ComponentScan自动扫描组件使用

article/2025/11/10 17:35:04

目录

无注解方式component-scan使用

注解方式@ComponentScan使用

@ComponentScan的扫描规则


无注解方式component-scan使用

之前,我们需要扫描工程下一些类上所标注的注解,这些常用注解有:

@Controller,@Service,@Component,@Repository

通过在Spring的配置文件中配置<context:component-scan>扫描对应包下扫描这些注解的方式:

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-2.5.xsd"><!--@Controller,@Service,@Component,@Repository--><context:component-scan base-package="com.jektong.spring"/></beans>

注解方式@ComponentScan使用

建三个类,依次将

@Controller@Repository@Service,标注这些类:

9676e1d230404d359e879afc90694c96.png

图1

现在通过使用注解@ComponentScan的方式来扫描所在包下面的这些类:之前定义的PersonConfig修改:

package com.jektong.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;import com.jektong.spring.Person;@Configuration
@ComponentScan("com.jektong")
public class PersonConfig {@Bean("person01")public Person person() {return new Person("李四",21);}
}

测试,看是否扫描到这些注解所标注的类:PersonTest.java

@Test
public  void test02() {ApplicationContext ac = new AnnotationConfigApplicationContext(PersonConfig.class);Person bean = ac.getBean(Person.class);System.out.println(bean);String[] beanDefinitionNames = ac.getBeanDefinitionNames();for (String string : beanDefinitionNames) {System.out.println(string);}
}

测试效果:除了Spring要自动加载的配置类以外也显示了刚才添加的配置类:

32af07a5fb0f442c916164f7f441bd35.png

图2

为何会出现PersonConfig,因为@Configuration本 身就是@Component注解的:

f3647d616e5145e68ca4f5c2c8a21616.png

图3

@ComponentScan的扫描规则

如果需要指定配置类的扫描规则, @ComponentScan提供对应的扫描方式@Filter进行配置类的过滤:

// 扫描包的时候只规定扫描一些注解配置类。
Filter[] includeFilters() default {};// 扫描包的时候可以排除一些注解配置类。 
Filter[] excludeFilters() default {};

Filter其实也是一个注解,相当于@ComponentScan的子注解,可以看图4

0616dc7cd25a4dcdb5ac759f50ab4230.png

图4

Filter对应的过滤规则如下:

第一种:扫描包的时候只规定扫描一些注解配置类【includeFilters】。

使用这个includeFilters过滤规则,必须解除默认的过滤规则,

使用【useDefaultFilters = false】

package com.jektong.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;import com.jektong.spring.Person;@Configuration
@ComponentScan(value = "com.jektong",includeFilters  = {@Filter(type = FilterType.ANNOTATION,value= {Controller.class})
},useDefaultFilters = false )
public class PersonConfig {@Bean("person01")public Person person() {return new Person("李四",21);}
}

这样就只会扫描用@Controller,标注的配置类交给Spring容器中了:

692b89ffdc8b4038977d5b4b8ebbbf94.png

图5

 第二种:扫描包的时候可以排除一些注解配置类【excludeFilters 】。

87f83f3d10824d1cb846cea234642191.png

图6

 @Filter看上图,有5种不同类型的过滤策略。拿第一种举例,我们需要过滤使用@Controller注解的配置类:

package com.jektong.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;import com.jektong.spring.Person;@Configuration
@ComponentScan(value = "com.jektong",excludeFilters = {@Filter(type = FilterType.ANNOTATION,value= {Controller.class})
} )
public class PersonConfig {@Bean("person01")public Person person() {return new Person("李四",21);}
}

测试看一下发现图2中的personController不会交给Spring容器去管理了:

1157d6b18b2f40d89f59310b3c624bf4.png

图7

上面的图6展示出5种不同类型的过滤策略,上面介绍了注解类型(FilterType.ANNOTATION),还有四种: 

重点看一下CUSTOM自定义扫描策略。

 

从源码看,自定义扫描注解类型需要实现TypeFilter接口,下面就写一个实现类MyFilter.java:在实现类中可以自定义配置规则:

package com.jektong.config;import java.io.IOException;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;public class MyFilter implements TypeFilter {@Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)throws IOException {// 查看当前类的注解。AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();// 查看当前扫描类的信息ClassMetadata classMetadata = metadataReader.getClassMetadata();// 获取当前类资源Resource resource = metadataReader.getResource();String className = classMetadata.getClassName();System.out.println("className===>" + className);// 只要类名包含er则注册Spring容器if(className.contains("er")) {return true;}return false;}
}

测试:

PersonConfig 中进行扫描:

package com.jektong.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;import com.jektong.service.PersonService;
import com.jektong.spring.Person;@Configuration
@ComponentScan(value = "com.jektong",includeFilters  = {@Filter(type = FilterType.CUSTOM,value= {MyFilter.class})
},useDefaultFilters = false )
public class PersonConfig {@Bean("person01")public Person person() {return new Person("李四",21);}
}

可以看出扫描出包下面的类只要带“er”的全部扫描出来,并配置给Spring容器:

ASSIGNABLE_TYPE:按照指定的类型去加载对应配置类:

package com.jektong.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;import com.jektong.service.PersonService;
import com.jektong.spring.Person;@Configuration
@ComponentScan(value = "com.jektong",includeFilters  = {@Filter(type = FilterType.ASSIGNABLE_TYPE,value= {PersonService.class})
},useDefaultFilters = false )
public class PersonConfig {@Bean("person01")public Person person() {return new Person("李四",21);}
}

尽管我们将PersonService.java上的注解去掉,使用ASSIGNABLE_TYPE依然会加载出来(自行测试)。

ASPECTJ与REGEX基本不用,不用了解。

以上就是@ComponentScan的具体用法,该兴趣的话可以看一下源码。


http://chatgpt.dhexx.cn/article/IcB9bV81.shtml

相关文章

Spring注解详解

一、Spring注解驱动开发入门 spring在2.5版本引入了注解配置的支持&#xff0c;同时从Spring 3版本开始&#xff0c;Spring JavaConfig项目提供的许多特性成为核心Spring框架的一部分。因此&#xff0c;可以使用Java而不是XML文件来定义应用程序类外部的bean。在这里面官方文档…

Spring常用注解的详细介绍(包你学明白)

目录 1. 为什么要使用注解&#xff1f; 2. 什么是注解&#xff1f; 3. 在Spring中使用注解的前期准备 4. Component注解的详细介绍 5. Value注解的详解介绍 6. Autowired注解的详细介绍 7. Resource注解的详细介绍 8. 怎么选择基于xml还是基于注解的方式创建对象并赋值呢…

Spring中的注解详细介绍

注&#xff1a;标颜色的需要重点掌握 一、Spring原始注解&#xff1a; Spring原始注解主要代替<bean>标签的配置。 1. Component 说明&#xff1a;使用在类上用于实例化Bean 2. Repository 说明&#xff1a;使用在dao层类上用于实例化…

isnumeric_Python字符串isnumeric()

isnumeric Python String isnumeric() function returns True if all the characters in the string are numeric, otherwise False. If the string is empty, then this function returns False. 如果字符串中的所有字符均为数字&#xff0c;则Python String isnumeric&#x…

isdigit isdecimal isnumeric 区别

一、代码测试 num "1" #unicode num.isdigit() # True num.isdecimal() # True num.isnumeric() # Truenum "1" # 全角 num.isdigit() # True num.isdecimal() # True num.isnumeric() # Truenum b"1" # byte num.isdigit() # True n…

StringUtils.isNumeric使用

网上查"java 判断字符串为数字"阅资料&#xff0c;大部分资料都在讲字符串转为整数的情况&#xff0c;很少资料提及关于负数和小数的情况&#xff0c;最终决定采用StringUtils.isNumberic这个方法差别&#xff0c; 在测试导出时发现有报错&#xff0c;用debug模块一…

Java 字符串的数字校验:isNumeric,isNumericSpace和正则表达式,对比分析

导读 数字类型的判断是项目里常见的场景&#xff0c;相比一大串的非空&#xff0c;instanceof 以及大于小于0的判断&#xff0c;我更倾向于使用工具类 StringUtils 或者 正则表达式 来实现功能&#xff0c;追求代码的简洁和高效。 你可能需要的博客&#xff1a; 正则表达式预编…

StringUtils.isNumeric(str)

在项目中遇到一处bug&#xff0c;调试的结果竟然是StringUtils.isNumeric(String str) 在捣鬼&#xff08;采用的是org.apache.commons.lang.StringUtils&#xff09;&#xff0c;下面的代码是判断一个参数非空&#xff0c;且为整数&#xff1a; if(StringUtils.isNumeric(str)…

第六十七章 SQL函数 ISNUMERIC

文章目录 第六十七章 SQL函数 ISNUMERIC大纲参数描述示例 第六十七章 SQL函数 ISNUMERIC 测试有效数字的数值函数。 大纲 ISNUMERIC(check-expression)参数 check-expression - 要计算的表达式。 ISNUMERIC返回SMALLINT数据类型。 描述 ISNUMERIC计算check-expression并…

isnumeric( )函数用法

isnumeric( )还是一个很实用的函数&#xff0c;在算法题目里面应该会有比较大的作用。 检测字符串是否只由数字组成&#xff0c;如果字符串中只包括数字&#xff0c;就返回Ture&#xff0c;否则返回False。 华为的一道算法题&#xff1a; 读入一个字符串str&#xff0c;输出字…

MAE:视觉自监督2021(原理+代码)

文章目录 前言一、MAE原理遮住95%的像素后&#xff0c;仍能还原出物体的轮廓&#xff0c;效果如图&#xff1a; 二、MAE测试代码1.models_mae.py1.1 self.forward_encoder1.2 self.forward_decoder1.3 loss self.forward_loss(imgs, pred, mask) 2.run_one_image 三、MAE升级版…

​一文看尽MAE最新进展!恺明的MAE已经提出大半年,目前发展如何?

©PaperWeekly 原创 作者 | Jason研究方向 | 计算机视觉 写在前面 自去年 11 月份恺明大神提出 MAE 来&#xff0c;大家都被 MAE 简单的实现、极高的效率和惊艳的性能所吸引。近几个月&#xff0c;大家也纷纷 follow 恺明的工作&#xff0c;在 MAE 进行改进&#xff08;如…

一文解读Masked Autoencoder(MAE)

前言 论文链接&#xff1a;https://arxiv.org/pdf/2111.06377.pdf   跟李沐学AI&#xff1a;https://www.bilibili.com/video/BV1sq4y1q77t?spm_id_from333.999.0.0   如果说Vision Transformer是Transformer在CV领域的拓展&#xff0c;那么Masked Autoencoder就是BERT在C…

matlab mse mae,回归评价指标MSE、RMSE、MAE、R-Squared

前言 分类问题的评价指标是准确率,那么回归算法的评价指标就是MSE,RMSE,MAE、R-Squared。下面一一介绍 均方误差(MSE) MSE (Mean Squared Error)叫做均方误差。看公式 image.png 这里的y是测试集上的。 用 真实值-预测值 然后平方之后求和平均。 猛着看一下这个公式是不是觉…

何凯明最新一作MAE(mask掉图片的部分信息也能重建识别)

导读 凯明出品&#xff0c;必属精品。没有花里胡哨的修饰&#xff0c;MAE就是那么简单的强大&#xff0c;即结构简单但可扩展性能强大。MAE通过设计一个非对称的编码解码器&#xff0c;在预训练阶段&#xff0c;通过高比例的掩码原图&#xff0c;将可见部分输入到编码器中&…

李沐精读论文:MAE 《Masked Autoencoders Are Scalable Vision Learners》

论文&#xff1a;Masked Autoencoders Are Scalable Vision Learners 别再无聊地吹捧了&#xff0c;一起来动手实现 MAE(Masked Autoencoders Are Scalable Vision Learners) 玩玩吧&#xff01; - 知乎 参考博文&#xff1a;MAE 论文逐段精读【论文精读】 - 哔哩哔哩 神洛华…

从Transformer到ViT再到MAE

从Transformer到VIT再到MAE 引言Transfomer提出的背景模型架构具体细节Add&NormAttention&#xff1a;Multi-Head Attention自注意力机制&#xff08;self attention&#xff09;Positional Encoding ViT提出的背景&#xff1a;模型架构&#xff1a;具体细节&#xff1a;维…

MAE简记

MAE简记 文章目录 MAE简记Mask 方法EncoderDecoderTarget & LOSS Mask 方法 将图片分割成不重复的正方形patch&#xff0c;遮挡其中一部分patch(75%) Encoder 采用ViT&#xff0c;但是只对可见的没有被masked的patch使用 Decoder 以encoder的输出masked的patch作为输入…

何凯明最新一作MAE解读系列1

导读 凯明出品&#xff0c;必属精品。没有花里胡哨的修饰&#xff0c;MAE就是那么简单的强大&#xff0c;即结构简单但可扩展性能强大。MAE通过设计一个非对称的编码解码器&#xff0c;在预训练阶段&#xff0c;通过高比例的掩码原图&#xff0c;将可见部分输入到编码器中&…

基于CIFAR数据集 进行 MAE实现及预训练可视化 (CIFAR for MAE,代码权重日志全部开源,自取)

基于CIFAR数据集 进行 MAE实现及预训练可视化 &#xff08;CIFAR for MAE&#xff0c;代码权重日志全部开源&#xff0c;自取&#xff09; 文章目录 基于CIFAR数据集 进行 MAE实现及预训练可视化 &#xff08;CIFAR for MAE&#xff0c;代码权重日志全部开源&#xff0c;自取&a…