1.创建一个配置类,在配置类上添加 @ComponentScan 注解。该注解默认会扫描该类所在的包下所有的配置类,相当于之前的 <context:component-scan>。

package io.mieux.config;import org.springframework.context.annotation.ComponentScan;@ComponentScan
public class BeanConfig {}

2.使用 ApplicationContext 的 getBeanDefinitionNames() 方法获取已经注册到容器中的 bean 的名称。

import io.mieux.config.BeanConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App02 {public static void main(String[] args) {ApplicationContext applicationContext =new AnnotationConfigApplicationContext(BeanConfig.class);String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();for (String beanName : beanDefinitionNames) {System.out.println("beanName: " + beanName);}}
}

运行效果:

beanName: org.springframework.context.annotation.internalConfigurationAnnotationProcessor
beanName: org.springframework.context.annotation.internalAutowiredAnnotationProcessor
beanName: org.springframework.context.annotation.internalRequiredAnnotationProcessor
beanName: org.springframework.context.annotation.internalCommonAnnotationProcessor
beanName: org.springframework.context.event.internalEventListenerProcessor
beanName: org.springframework.context.event.internalEventListenerFactory
beanName: beanConfig

除了 spring 本身注册的一些 bean 之外,可以看到最后一行,已经将 BeanConfig 这个类注册进容器中了。

3.指定要扫描的包(使用@ComponentScan 的 valule 属性来配置),创建一个controller 包,并在该包下新建一个 AppController 类。

package io.mieux.controller;import org.springframework.stereotype.Controller;@Controller
public class AppController {}

在类上加了@Controller注解,说明该类是一个 Component。在 BeanConfig 类中修改:

package io.mieux.config;import org.springframework.context.annotation.ComponentScan;@ComponentScan(value = "io.mieux.controller")
public class BeanConfig {}

在 @ComponentScan 注解中指定了要扫描的包。

运行效果:

beanName: org.springframework.context.annotation.internalConfigurationAnnotationProcessor
beanName: org.springframework.context.annotation.internalAutowiredAnnotationProcessor
beanName: org.springframework.context.annotation.internalRequiredAnnotationProcessor
beanName: org.springframework.context.annotation.internalCommonAnnotationProcessor
beanName: org.springframework.context.event.internalEventListenerProcessor
beanName: org.springframework.context.event.internalEventListenerFactory
beanName: beanConfig
beanName: appController

AppController 已经被注册进容器了。

4.excludeFilters 和 includeFilters 的使用

使用 excludeFilters 来按照规则排除某些包的扫描。

package io.mieux.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;@ComponentScan(value = "io.mieux",excludeFilters = {@Filter(type = FilterType.ANNOTATION,value = {Controller.class})})
public class BeanConfig {}

excludeFilters 的参数是一个 Filter[] 数组,然后指定 FilterType 的类型为 ANNOTATION,也就是通过注解来过滤,最后的 value 则是Controller 注解类。配置之后,在 spring 扫描的时候,就会跳过 io.mieux 包下,所有被 @Controller 注解标注的类。

使用 includeFilters 来按照规则只包含某些包的扫描。

在创建一个 service 的包,并创建一个 AppService 类,再加上一个 @Service 注解。

package io.mieux.service;import org.springframework.stereotype.Service;@Service
public class AppService {}

修改 BeanCofig 类:

package io.mieux.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;@ComponentScan(value = "io.mieux", includeFilters = {@Filter(type = FilterType.ANNOTATION, classes = {Controller.class})})
public class BeanConfig {}

运行效果:

beanName: org.springframework.context.annotation.internalConfigurationAnnotationProcessor
beanName: org.springframework.context.annotation.internalAutowiredAnnotationProcessor
beanName: org.springframework.context.annotation.internalRequiredAnnotationProcessor
beanName: org.springframework.context.annotation.internalCommonAnnotationProcessor
beanName: org.springframework.context.event.internalEventListenerProcessor
beanName: org.springframework.context.event.internalEventListenerFactory
beanName: beanConfig
beanName: appController
beanName: appService

配置里面,应该是只包含 @Controller 注解的类才会被注册到容器中,为什么 @Service 注解的类也被注册了呢?这里涉及到 @ComponentScan 的一个 useDefaultFilters 属性的用法,该属性默认值为 true,也就是说 spring 默认会自动发现被 @Component、@Repository、@Service 和 @Controller 标注的类,并注册进容器中。要达到只包含某些包的扫描效果,就必须将这个默认行为给禁用掉(在 @ComponentScan 中将 useDefaultFilters 设为 false 即可)。

package io.mieux.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;@ComponentScan(value = "io.mieux", includeFilters = {@Filter(type = FilterType.ANNOTATION, classes = {Controller.class})},useDefaultFilters = false)
public class BeanConfig {}

运行效果:

beanName: org.springframework.context.annotation.internalConfigurationAnnotationProcessor
beanName: org.springframework.context.annotation.internalAutowiredAnnotationProcessor
beanName: org.springframework.context.annotation.internalRequiredAnnotationProcessor
beanName: org.springframework.context.annotation.internalCommonAnnotationProcessor
beanName: org.springframework.context.event.internalEventListenerProcessor
beanName: org.springframework.context.event.internalEventListenerFactory
beanName: beanConfig
beanName: appController

5.添加多种扫描规则

1、如果使用的 jdk8,则可以直接添加多个 @ComponentScan 来添加多个扫描规则,但是在配置类中要加上 @Configuration 注解,否则无效。

package io.mieux.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@ComponentScan(value = "io.mieux.controller")
@ComponentScan(value = "io.mieux.service")
@Configuration
public class BeanConfig {}

2、也可以使用 @ComponentScans 来添加多个 @ComponentScan,从而实现添加多个扫描规则。同样,也需要加上 @Configuration 注解,否则无效。

package io.mieux.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;@ComponentScans(value = {@ComponentScan(value = "io.mieux.controller"),@ComponentScan(value = "io.mieux.service")})
@Configuration
public class BeanConfig {}

6.添加自定义过滤规则

在前面使用过 @Filter 注解,里面的 type 属性是一个 FilterType 的枚举类型:

public enum FilterType {ANNOTATION,ASSIGNABLE_TYPE,ASPECTJ,REGEX,CUSTOM}

使用 CUSTOM 类型,就可以实现自定义过滤规则。

1、 首先创建一个实现 TypeFilter 接口的 CustomTypeFilter 类,并实现其 match 方法。

package io.mieux.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 CustomTypeFilter implements TypeFilter {@Overridepublic boolean match(MetadataReader metadataReader,MetadataReaderFactory metadataReaderFactory) throws IOException {// 获取当前扫描到的类的注解元数据AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();// 获取当前扫描到的类的元数据ClassMetadata classMetadata = metadataReader.getClassMetadata();// 获取当前扫描到的类的资源信息Resource resource = metadataReader.getResource();if (classMetadata.getClassName().contains("Co")) {return true;}return false;}
}

这里简单对扫描到的类名进行判断,如果类名包含”Co“的就符合条件,也就会注入到容器中。

2、对 BeanConfig 进行修改,指定过滤类型为 Custom 类型,并指定 value 为 CustomTypeFilter.class。

package io.mieux.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;@ComponentScan(value = "io.mieux",includeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, value = {CustomTypeFilter.class})},useDefaultFilters = false)
public class BeanConfig {}

运行效果:

beanName: org.springframework.context.annotation.internalConfigurationAnnotationProcessor
beanName: org.springframework.context.annotation.internalAutowiredAnnotationProcessor
beanName: org.springframework.context.annotation.internalRequiredAnnotationProcessor
beanName: org.springframework.context.annotation.internalCommonAnnotationProcessor
beanName: org.springframework.context.event.internalEventListenerProcessor
beanName: org.springframework.context.event.internalEventListenerFactory
beanName: beanConfig
beanName: appController

Spring注解——使用@ComponentScan自动扫描组件相关推荐

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

    目录 无注解方式component-scan使用 注解方式@ComponentScan使用 @ComponentScan的扫描规则 无注解方式component-scan使用 之前,我们需要扫描工程下 ...

  2. Spring注解驱动之注册组件(spring的再回顾)

    一. 组件注册 1. 给容器中注册组件 xml方式 创建一个实体类(构造方法等省略) public class Person {private String name;private Integer ...

  3. 【Spring源码系列】Spring注解扫描-@ComponentScan底层原理解读

    这里写目录标题 前言 一.Spring扫描-@ComponentScan注解介绍 @ComponentScan作用 @ComponentScan重要参数 二.Spring扫描-源码分析 声明关键点 源 ...

  4. 组件注册——@ComponentScan自动扫描组件指定扫描规则

    包扫描.只要标注了@Controller.@Service.@Repository,@Component IOCTest.java package com.atguigu.test;import or ...

  5. Spring注解开发(Springboot源码必备前置知识)

    学无止境 Java工程师的进阶之旅 目录 一.组件注册(IOC) 概述 1.@Configuration @Bean 2.@ComponentScan 3.@Scope 4.@Lazy 5.@Cond ...

  6. 0、Spring 注解驱动开发

    0.Spring注解驱动开发 0.1 简介 <Spring注解驱动开发>是一套帮助我们深入了解Spring原理机制的教程: 现今SpringBoot.SpringCloud技术非常火热,作 ...

  7. Spring自动扫描组件

    通常情况下,声明所有的Bean类或组件的XML bean配置文件,这样Spring容器可以检测并注册Bean类或组件. 其实,Spring是能够自动扫描,检测和预定义的项目包并实例化bean,不再有繁 ...

  8. Spring注解开发系列Ⅰ--- 组件注册(上)

    传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文 ...

  9. spring注解开发:容器中注册组件方式

    1.包扫描+组件标注注解 使用到的注解如下,主要针对自己写的类 @Controller @Service @Repository @Component @ComponentScan 参考 spring ...

最新文章

  1. python逆转字符串封装_Python 实现文本操作之逆转字符串
  2. tortoisegit 常见错误disconnected no supported authentication methods available(server sent: publickey)
  3. 无法打开内核设备“\\.\Global\vmx86”: 系统找不到指定的文件
  4. 360加固一键脱壳工具2020_如何脱壳加固过的Apk并利用其API“走近数据库”
  5. P5488-差分与前缀和【NTT,生成函数】
  6. uboot环境变量与内核MTD分区关系
  7. Fragment的知识总结
  8. mven2 + androMDA 初探
  9. word创建Pdf时嵌入字体 Creating a PDF with Embedded Fonts for MS Word
  10. 贝叶斯网络:故障诊断方法研究
  11. Android 中的转场动画及兼容处理
  12. 项目合同管理 试题分析
  13. Java爬虫系列之二网页解析【爬取知乎首页信息】
  14. 需要精读3遍的8个健身知识
  15. 优麒麟 20.04 pro更换内核
  16. maps-api-v3_利用Google Maps API发挥创意
  17. 跟宁哥学Go语言视频课程(10):反射-李宁-专题视频课程
  18. STM32F105双CAN双FIFO通讯心得体会
  19. Arnold阿诺德渲染器:C4DtoA for Cinema4D R20 for Mac
  20. FLUENT操作--VOF模型局部初始化的TUI命令

热门文章

  1. 桶分类 算法_桶分类算法
  2. stl make_heap_通过使用make_heap()创建堆| C ++ STL
  3. php发展历,PHP的发展历程
  4. python怎么变各种颜色_python – 如何淡化颜色
  5. 微商相册一直显示服务器偷懒,【小程序】微商个人相册多端小程序源码以及安装...
  6. vue 导出_Vue核心知识:8.3 vuex在vue-cli中的应用,文件之间的导出与引入
  7. observable_Java Observable notifyObservers()方法与示例
  8. Java调优:Mybaitis的缓存优化
  9. python基本的信号与槽函数的使用 信号发射 槽函数接收
  10. CentOS7 源码编译安装MySQL8.0.15 shell脚本