自动装配机制1

简介: 本文深入解析SpringBoot自动装配机制,从@SpringBootApplication注解入手,剖析其组合注解原理,重点讲解@ComponentScan、@SpringBootConfiguration及元注解的作用与源码实现,揭示组件扫描与过滤的底层逻辑。

前言

SpringBoot主启动类被@SpringBootApplication所修饰,点击进去该注解,出现上图,会发现其为组合注解,本章节将会基于注解进行解释其自动装配在源码层面是怎么实现的,完整的注解调用链路如下图所示:

1.元注解

@Target注解


  • 注解的作用目标
  • @Target(ElementType.TYPE)                                           //接口、类、枚举、注解
  • @Target(ElementType.FIELD)                                         //字段、枚举的常量
  • @Target(ElementType.METHOD)                                   //方法
  • @Target(ElementType.PARAMETER)                              //方法参数
  • @Target(ElementType.CONSTRUCTOR)                        //构造函数
  • @Target(ElementType.LOCAL_VARIABLE)                     //局部变量
  • @Target(ElementType.ANNOTATION_TYPE)                //注解
  • @Target(ElementType.PACKAGE)                                 //包    

@Retention注解


  • 修饰注解,是注解的注解,称为元注解
  • SOURCE,     // 编译器处理完Annotation后不存储在class中  
  • CLASS,       // 编译器把Annotation存储在class中,这是默认值  
  • RUNTIME  // 编译器把Annotation存储在class中,可以由虚拟机读取,反射需要

@Documented注解

  • 这个Annotation可以被写入javadoc

上述三个元注解也是实现自定义注解的基础,不是很清楚的可以先看这篇:自定义注解

@Inherited 注解

@SpringBootApplication注解被@Inherited修饰,则SpringBoot主启动类也就具备了@SpringBootApplication注解的:

@SpringBootConfiguration

@EnableAutoConfiguration

@ComponentScan

2.@ComponentScan注解


这个注解原来在SpringFramework中比较常见,而且其出现位置为配置文件:spring配置文件的applicationContext.xml或者springmvc的配置文件中,用来标识:扫描的包路径,这样就可以将我们定义的注解扫描进去。

在SpringBoot中,其关键作用是:默认扫描当前配置类所在包及子包下的所有组件, exclude 属性会将主启动类、自动配置类屏蔽掉

2.1 TypeExcludeFilter注解

其核心代码简单PO出,依赖BeanFactory,这个BeanFactory就是SpringFramework接口体系中的顶层,定义了基本的方法,如:getBean,containsBean,isSingleton,getType,isTypeMatch等。如下图(体系要比这个更丰富,推荐大家自己在Idea中生成查看,看SpringBoot源码的前提,建议先看Spring源码):

TypeExcludeFilter核心方法为match(),其关键作用在于:拓展组件的过滤提供一种扩展机制,能让我们向IOC容器中注册一些自定义的组件过滤器,以在包扫描的过程中过滤它们会从 BeanFactory 中获取所有类型为 TypeExcludeFilter 的组件,去执行自定义的过滤方法。

2.2 AutoConfigurationExcludeFilter注解

其核心方法和TypeExcludeFilter一样,match()方法,但是实现有所区别,AutoConfigurationExcludeFilter的核心是:判断是否是一个配置类,且同时是否是一个自动配置的配置类

2.3 问题:SpringBoot怎么过滤不需要的组件

面试题】:Spring IOC容器在boot中也是存在的对吧,那有一些Bean我不想在启动时就注入IOC容器,这种情况有遇到过吗?

【个人理解】:目前还没遇到,不过要是实现的话,在启动类上加上@ComponentScan注解,在value中写上指定的:*.class是可以实现的【参见2.4小结】,或继承TypeExcludeFilter ,重写match方法,如默认会加载com.test.TestService这个bean,则重写的方法中,

public class MyTypeExcludeFilter extends TypeExcludeFilter {
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
            throws IOException {
        if("com.test.TestService".equals(metadataReader.getClassMetadata().getClassName())){
            return false;
        }
        return true;
    }
}

或者直接在boot配置文件中添加,其是支持的【但是我没细究如何配置,这个百度下应该就有】,如下:

2.4 小结

上述之后我们都能知道两个Exclude都有match方法,但是匹配什么?过滤什么?至少我在第一次看的时候还是很懵的,目前我的认知总结如下,可能不是很准确,提供出来给大家参考一下:

@ComponentScan注解会扫描Bean完成IOC注入,但是有一部分我们是不需要注入进IOC容器的,那么这种场景下我们就可以借助于我们这一小章节的注解进行实现,其实现方法就是:

import org.springframework.context.annotation.FilterType;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {TestBean.class})})

这种方式是官方给的一个参考方式,但是我们也可以清楚的看到弊端:仅适用于少量的,如果需要规避的扫描类很多,这个classes将会变的非常冗杂,当然也有很多解决方案,如继承TypeExcludeFilter ,重写match方法,更多方式自行百度下就行。

关于@AutoConfigurationExcludeFilter,能搜到的资料很少,区别就在于多了一部分AutoConfiguration,所以我目前的认知是:二者都能用来处理组件过滤,但是是TypeFilter接口的两种实现,一种主要服务于主启动类组件,一种服务于自动配置的组件,二者结合实现一个完整的组件过滤

图的BeanFactoryAware,BeanClassLoaderAware在Spring IOC容器中比较常见,也是Spring的Bean生命周期中会遇到的组件,这里就不再赘述,有需要的百度学习下即可,贴个简单的IOC接口体系(实际要更丰富)。

3.@SpringBootConfiguration注解

官方给的解释也是:@SpringBootConfiguration 是对 @Configuration注解(这个我们可能就比较熟悉了,不了解的参考:@Configuration)的一种封装,在上图我们也可看出,其核心作用是:标注在配置类上,且是主启动类(如果@Configuration标注就不必强调是主启动类),基于这个注解,其所在的包路径位置获取之后EnableAutoConfiguration(第4节详细论述)注解扫描的依据,进而扫描出配置文件。

这里也说明了为什么SpringBoot的主启动类,我们是放在包的最外层,因为只有这样,我们的basePackage才能够获取到全部组件。

相关文章
|
8月前
|
存储 缓存 监控
EFC&CTO:缓存引发数据不一致问题排查与深度解析
EFC客户端在NAS场景下因缓存版本号回退,导致读取旧数据并写坏文件系统。通过日志分析发现,慢请求致dv回退,buffer write时读入NULL覆盖正常数据。修复后测试通过,问题源于分布式缓存与pagecache协同异常。
 EFC&CTO:缓存引发数据不一致问题排查与深度解析
|
8月前
|
测试技术 UED
发布模式
蓝绿部署通过两套系统(蓝/绿)并行,实现零停机发布与快速回滚;金丝雀发布逐步替换旧版本,降低风险;A/B测试则对比多版本效果,优化用户体验。三者各有适用场景,非万能方案。
|
8月前
|
安全 Java 数据安全/隐私保护
认识SpringSecurity
Spring Security 是基于过滤器链的成熟安全框架,提供认证、鉴权及防御 CSRF 等攻击的核心功能,支持多种认证方式与灵活的权限控制模型。
|
8月前
|
Java Linux Docker
Docker
本文介绍Docker基础操作,涵盖镜像打包、容器管理及Dockerfile编写。通过实例演示如何构建镜像、运行容器并验证服务,适合初学者快速掌握Docker核心技能。
 Docker
|
8月前
|
运维 安全 Devops
生产环境缺陷管理
git-poison基于go-git实现分布式bug追溯,通过“投毒/解毒/银针”机制,自动化管理多分支场景下的bug修复与发布卡点,避免人为疏漏,提升发布安全与效率,已在大型团队落地应用。
 生产环境缺陷管理
|
8月前
|
开发者
业务架构图
本文介绍了业务架构图的核心概念与绘制方法,涵盖业务定义、架构分层逻辑及业务架构图的三大核心要义:分层、分模块、分功能。通过医院案例解析,阐明如何将现实业务抽象为清晰的架构模型,并强调信息流设计与模块边界的合理性,助力客户理解与开发者协作。
 业务架构图
|
8月前
|
数据采集 领域建模 数据库
领域模型图(数据架构/ER图)
本文介绍如何通过四色原型法构建领域模型,并逐步提炼出ER图。采用红色(时标性)、绿色(参与方-物品-地点)、黄色(角色)和蓝色(描述)四类原型,从业务流程中抽象数据实体与关系,最终形成清晰的数据架构模型,指导数据库设计。
 领域模型图(数据架构/ER图)
|
8月前
|
运维 Kubernetes Java
物理部署图
物理部署图描述系统运行时的硬件配置与软件部署结构,展现节点、构件、物件及连接关系,帮助理解分布式系统的部署架构,是连接开发与运维的重要视图。
|
8月前
|
Java 应用服务中间件 网络安全
Eclipse运行SSM/SSH项目教程
本文介绍了如何在Eclipse中导入并运行Java Web项目,涵盖基础软件(Eclipse、JDK、Tomcat)的安装与配置,详细演示了项目导入步骤及Eclipse绑定Tomcat的方法。同时提供常见错误排查,如数据库连接信息修改,并附有案例项目与视频讲解,助力快速部署SSM/SSH项目。
 Eclipse运行SSM/SSH项目教程
|
8月前
|
存储 缓存 算法
零拷贝
实现文件传输时,传统方式因频繁的上下文切换和内存拷贝导致性能低下。零拷贝技术通过减少系统调用和数据拷贝次数,提升传输效率。结合PageCache、异步IO与直接IO,可针对不同场景优化性能,尤其在大文件传输中避免缓存污染,兼顾速度与资源利用。
零拷贝

热门文章

最新文章