【Spring注解】@ComponentScan之 你可能没注意到的点

2022-07-06 12:56:15

本博客的demo源码

源码地址:https://github.com/nieandsun/spring-study

一、@ComponentScan的作用

  • @ComponentScan注解有两个作用

    • 扫描含有@Component,@Controller,@Service和@Repository的类,并将其注入到spring容器中。
    • 扫描含有@Configuration的类,并使其生效。

二、demo的目录结构

在这里插入图片描述

三、@ComponentScan作用演示

  • 扫描含有@Component,@Controller,@Service和@Repository的类,并将其注入到spring容器中。

  相信大家都知道这个作用,这里不再演示,有需要的可以去我的github上下载源码,进行测试。

  • 扫描含有@Configuration的类,并使其生效。

  如上图所示,Config2可以扫描到config2_test目录,该目录下不仅含有@Component,@Controller,@Service和@Repository注解标注的四个类,还包含Config1配置类。Config1配置类,可以扫描到config1_test目录,并且里面还包含一个@Bean注解。
Config1配置类代码如上图所示
Config2配置类代码如下:

package com.nrsc.springstudy.c1_componentscan.config;import com.nrsc.springstudy.c1_componentscan.config2_test.OrderRepository2;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;//标识此类为注解类@Configuration//扫描config2_test目录,并排除OrderRepository2类@ComponentScan(value="com.nrsc.springstudy.c1_componentscan.config2_test",
        excludeFilters={@Filter(type= FilterType.ASSIGNABLE_TYPE, classes={OrderRepository2.class})})publicclassConfig2{}

项目启动代码如下:

@Testpublicvoidtest02(){//加载Config2配置类
        AnnotationConfigApplicationContext ac=newAnnotationConfigApplicationContext(Config2.class);
        String[] names= ac.getBeanDefinitionNames();for(String name: names){
            System.out.println(name);}}

运行结果如下:
在这里插入图片描述

四、多个@ComponentScan以及@ComponentScans

  • 结论:如果有多个@ComponentScan时,各个@ComponentScan扫描到的类的交集都会被注册到spring容器中。

  具体代码不再展示,如demo的目录结构图所示,Config5配置类将扫描config5_test目录下除了OrderRepository5之外的类,Config5_1配置类只扫描OrderRepository5和BuyComponent5两个类,当按Config5配置类启动项目时,会把Config5_test目录下所有的类都注册到spring容器中,效果如下:
在这里插入图片描述

注意点----同一个配置类上多个@ComponentScan可能会报错

下面的配置类在我公司电脑的idea版本里是可以将config3_test目录下的所有类都注册到spring容器中,但是在我家里的电脑上以及另一个同事的电脑上会报编译期错误,代码运行也会出错。

package com.nrsc.springstudy.c1_componentscan.config;import com.nrsc.springstudy.c1_componentscan.config3_test.OrderRepository3;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;@Configuration//扫描整个config3_test目录@ComponentScan(value="com.nrsc.springstudy.c1_componentscan.config3_test")//扫描除了OrderRepository3类之外的config3_test目录@ComponentScan(value="com.nrsc.springstudy.c1_componentscan.config3_test",
        excludeFilters={@Filter(type= FilterType.ASSIGNABLE_TYPE, classes={OrderRepository3.class})})publicclassConfig3{}

同事电脑上报错截图如下:

  • 编译期异常

在这里插入图片描述

  • 运行期异常

在这里插入图片描述

@ComponentScans的使用

由于同一个类上直接写多个@ComponentScan可能会报错,因此建议使用@ComponentScans,它可以解决直接在一个配置类上写多个@ComponentScan在有些电脑或idea版本上报错的问题,代码如下:

package com.nrsc.springstudy.c1_componentscan.config;import com.nrsc.springstudy.c1_componentscan.config4_test.OrderRepository4;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.ComponentScans;import org.springframework.context.annotation.ComponentScan.Filter;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.FilterType;@Configuration@ComponentScans(value={@ComponentScan(value="com.nrsc.springstudy.c1_componentscan.config4_test"),@ComponentScan(value="com.nrsc.springstudy.c1_componentscan.config4_test",
                excludeFilters={@Filter(type= FilterType.ASSIGNABLE_TYPE, classes={OrderRepository4.class})})})publicclassConfig4{}
  • 作者:nrsc
  • 原文链接:https://blog.csdn.net/nrsc272420199/article/details/88352637
    更新时间:2022-07-06 12:56:15