springboot2.x基础教程:@Enable*原理

SpringBoot 学习笔记 (三) SpringBoot 自动配置 | Condition的实现 | 切换web内置服务器 | @Enable 注解 | @Import注解 |自动配置模拟实现 文章目录参考资料运行环境SpringBoot 自动配置原理一、Condition二、切换内置web服务器三、Enable*注解四、Import 注解五、@EnableAutoConfiguration 注解六、案例七、收获与总结 参考资料 视频链接 运行环境 win10 IDEA专业版 SpringBoot 2.6.2 SpringBoot 自动配置原理 一、Condition Condition 是在 Spring 4.0 增加的条件判断功能,作用是实现选择性的创建Bean操作 思考: Spr 阅读详情

上一篇springboot2.x基础教程:@Async开启异步任务我们使用了@EnableAsync注解来启用异步执行。
SpringBoot框架中@Enable*注解有很多例如:@EnableAspectJAutoProxy、@EnableCaching、@EnableAutoConfiguration、@EnableSwagger2这一章讲讲它背后的原理。

几个典型的@Enable*注解

下面贴出@EnableSwagger2、@EnableAsync、@EnableAspectJAutoProxy这三个注解,不难看出这三个注解都使用了@Import注解。
@Import注解支持导入普通的java类,并将其声明成一个bean。
实际@Enable注解就是通过@Import注解的能力实现Bean的注入springboot ioc容器,从而使某些配置生效。

@EnableScheduling

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({SchedulingConfiguration.class})
@Documented
public @interface EnableScheduling {
}

@EnableAsync

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AsyncConfigurationSelector.class})
public @interface EnableAsync {
    Class<? extends Annotation> annotation() default Annotation.class;
    boolean proxyTargetClass() default false;
    AdviceMode mode() default AdviceMode.PROXY;
    int order() default 2147483647;
}

@EnableAspectJAutoProxy

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;

    boolean exposeProxy() default false;
}

@Import注解使用方式

允许使用@Configuration注解的类

@EnableScheduling注解的@Import导入的是SchedulingConfiguration类,我们看下该类的实现。
我们可以看到该类使用了@Configuration、@Bean注解。
@Import注解允许使用@Configuration注解的类注入容器中。

@Configuration
@Role(2)
public class SchedulingConfiguration {
    public SchedulingConfiguration() {
    }
    @Bean(
        name = {"org.springframework.context.annotation.internalScheduledAnnotationProcessor"}
    )
    @Role(2)
    public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
        return new ScheduledAnnotationBeanPostProcessor();
    }
}

允许使用实现ImportSelectorj接口的类

@EnableAsync注解的@Import导入的是AsyncConfigurationSelector类,我们看下该类实现。
AsyncConfigurationSelector类实现了ImportSelector接口,重写了selectImports方法。
@Import注解这里会把selectImports返回的全路径的类注入容器中。

public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
    private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME = "org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";

    public AsyncConfigurationSelector() {
    }

    @Nullable
    public String[] selectImports(AdviceMode adviceMode) {
        switch(adviceMode) {
        case PROXY:
            return new String[]{ProxyAsyncConfiguration.class.getName()};
        case ASPECTJ:
            return new String[]{"org.springframework.scheduling.aspectj.AspectJAsyncConfiguration"};
        default:
            return null;
        }
    }
}

允许是实现了ImportBeanDefinitionRegistrar接口的类

@EnableAspectJAutoProxy注解的@Import导入的是AspectJAutoProxyRegistrar类,我们再看看该类实现。
AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,ImportBeanDefinitionRegistrar的作用是在运行时自动添加Bean到已有的配置类,并在Spring容器启动时解析生成bean,通过重写方法registerBeanDefinitions。

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    AspectJAutoProxyRegistrar() {
    }

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }

            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }
}

@Import注解SpringBoot处理流程源码分析

  1. Spring IOC容器初始化的时候会调用AbstractApplicationContext的refresh方法
  2. 在refresh里会调用各种BeanFactoryPostProcessor。ConfigurationClassPostProcessor的processConfigBeanDefinitions方法有对@Configuration、@Import等对注解的处理。
  3. ConfigurationClassPostProcessor实际内部通过ConfigurationClassParser处理。
  4. 我们重点看看ConfigurationClassParser这个类对@Import处理。

ConfigurationClassParser类源码分析

核心处理代码在ConfigurationClassParser的processImports方法中,实现了对于本文对于@Import三种使用方式的处理过程。

  private void processImports(ConfigurationClass configClass, ConfigurationClassParser.SourceClass currentSourceClass, Collection<ConfigurationClassParser.SourceClass> importCandidates, Predicate<String> exclusionFilter, boolean checkForCircularImports) {
	//....省略部分代码
                        ConfigurationClassParser.SourceClass candidate = (ConfigurationClassParser.SourceClass)var6.next();
                        Class candidateClass;
                        if (candidate.isAssignable(ImportSelector.class)) {
							//对于处理ImportSelector注解处理
                            candidateClass = candidate.loadClass();
                            ImportSelector selector = (ImportSelector)ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class, this.environment, this.resourceLoader, this.registry);
                            Predicate<String> selectorFilter = selector.getExclusionFilter();
                            if (selectorFilter != null) {
                                exclusionFilter = exclusionFilter.or(selectorFilter);
                            }
                            if (selector instanceof DeferredImportSelector) {
                                this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector)selector);
                            } else {
                                String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
                                Collection<ConfigurationClassParser.SourceClass> importSourceClasses = this.asSourceClasses(importClassNames, exclusionFilter);
                                this.processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
                            }
                        } else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
							//对于ImportBeanDefinitionRegistrar接口处理
                            candidateClass = candidate.loadClass();
                            ImportBeanDefinitionRegistrar registrar = (ImportBeanDefinitionRegistrar)ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class, this.environment, this.resourceLoader, this.registry);
                            configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
                        } else {
                            this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
							//对于@Configuration注解处理
                            this.processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
                        }
	//....省略部分代码
    }

千里之行,始于足下。这里是SpringBoot教程系列第十一篇,所有项目源码均可以在我的GitHub上面下载源码。

智能车图像处理2-入门级分析1 ---基础扫线 PS :入门级文章适合新手,如果已经有基础可以去看进阶篇文章。 阅读详情

相关推荐

宝塔面板+pbootCMS建站全流程:从服务器选购到上线优化(附常见问题排查)

本文提供了一份详尽的宝塔面板与pbootCMS建站实战指南。内容涵盖从云服务器选购、宝塔面板部署与安全加固,到pbootCMS安装、权限配置、数据库连接等核心步骤。同时深入讲解了PHP环境优化、Nginx伪静态设置、缓存开启等性能与SEO优化技巧,并附有常见问题排查与后期维护建议,帮助用户高效、稳健地完成专业网站构建。

e4f5g6h的博客 661

springboot-@Enablexxx原理

为什么会写这篇?@EnableConfigurationProperties 看名字很容易被误解成为引入某个properties文件。但其实不是,这个是开启某种配置 ,真正的是 Enable 某个@ConfigurationProperties注解的类 这篇从代码角度看下@EnableAutoConfiguration的流程。 springboot里有许多的@Enablexxxx,比如 ...

guo_xl的专栏 865

Power BI Report Server自定义登录实战:从AD切换到Form的完整流程(附GitHub源码)

本文详细介绍了如何将Power BI Report Server的登录认证从Active Directory切换到自定义Form认证的完整流程。通过环境准备、认证模块编译、配置脚本修改等步骤,帮助用户实现品牌统一的登录界面和简化外部用户访问。附有GitHub源码,适用于需要个性化登录解决方案的企业。

pz890123456的博客 209

Springboot2(43)轻松搞定自定义@Enable模块装配

源码地址 springboot2教程系列 在spring-boot框架中@EnableAutoConfiguration 开启自动扫描装配Bean 实现方式 注解方式 编程方式 背景 在学习SpringBoot的时候,我们会使用到@Enable***注解的地方,使用上也都是加在@Configuration 类注解的类上面,比如: (1)@EnableAutoConfiguration ...

cowbin2012的专栏 2万+

现代密码学5.3--Hash and MAC

现代密码学5.3--Hash and MAC 博主正在学习INTRODUCTION TO MODERN CRYPTOGRAPHY (Second Edition) --Jonathan Katz, Yehuda Lindell,做一些笔记供自己回忆,如有错误请指正。整理成一个系列现代密码学,方便检索。 第二章定义了完美安全及其对应的密码方案“一次一密”, 第三章介绍了多种安全定义 3.1-3.3 计算安全,PRG和基于PRG构造的满足计算安全的密码方案; 3.4-3.5 CPA安全,PRF和基于PRF构

qq_41545715的博客 685

ESP32锂电池电量检测实战:从引脚选择到低功耗优化(附完整电路图)

本文详细介绍了ESP32锂电池电量检测的实战方案,从ADC引脚选择到低功耗优化,提供完整的电路图和代码实现。通过MOS管智能开关和深度睡眠技术,显著降低静态功耗至0.5μA,提升设备续航能力。适合物联网开发者解决电量检测中的常见问题。

weixin_28731223的博客 462

Spring-Boot之@Enable*注解的工作原理

@enable*是springboot中用来启用某一个功能特性的一类注解。其中包括我们常用的@SpringBootApplication注解中用于开启自动注入的annotation@EnableAutoConfiguration,开启异步方法的annotation@EnableAsync,开启将配置文件中的属性以bean的方式注入到IOC容器的annotation@EnableConfigura...

很多时候犯错都是在不知情的情况下发生的 6439

ADSP-21565的SigmaStudio图形化编程实战:从FW工程改造到音频通道打通

本文详细介绍了如何将ADSP-21569的SigmaStudio图形化编程固件工程改造,以适配ADSP-21565的纯片内SRAM内存架构。通过修改内存映射和链接文件,打通了音频输出通道,并成功利用SigmaStudio进行图形化编程,实现了从白噪声生成到音频输出的完整验证流程。

weixin_29169505的博客 380

spring boot 自定义@EnableXXX注解

前言 spring boot 自带了很多@EnableXXX这样的注解,通过这些注解我们可以很方便地启用某些功能,比如@EnableAutoConfiguration用来开启自动装配的功能。内部实现主要是通过@Import注解将指定的类实例注入之Spring IOC Container中,从下面代码可以看到@EnableAutoConfiguration的@Import @Target(Eleme...

雷X峰 7849

RT-Thread网络编程:基于STM32F407的TCP客户端实现(含完整代码解析)

本文详细介绍了在STM32F407平台上,基于RT-Thread操作系统和LWIP协议栈实现工业级可靠TCP客户端的完整过程。内容涵盖底层ETH驱动配置、Socket编程、连接保活与断线重连机制、数据收发协议设计以及资源管理,提供了可应用于实际项目的健壮代码框架与调试技巧。

weixin_29184371的博客 492

【华为OD机试】真题E卷-一种字符串压缩表示的解压(C++)

有一种简易压缩算法:针对全部为小写英文字母组成的字符串,将其中连续超过两个相同字母的部分压缩为连续个数加该字母,其他部分保持原样不变。例如:字符串aaabbccccd 经过压缩变成字符串 3abb4cd请您编写解压函数,根据输入的字符串, 判断其是否为合法压缩过的字符串若输入合法则输出解压缩后的字符串 否则输出字符串!error来报告错误。

u014481728的博客 894

SpringBoot @EnableXX的实现原理

很少自己写spring boot starter, 看过了过久了也会忘记,写个笔记记录下。 @Enablexx @EnableAutoConfiguration @AutoConfigurationImportSelector 以@EnableWebSocket为例分析下原理 首先springboot工程引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>s

weixin_29335169的博客 595

电机控制基础,小白入门篇

电机,这个藏在风扇、电动车、机器人里的“动力心脏”,如何精准控制它的转速、方向甚至力量?这篇博客专为完全零基础的小白打造,用“说人话”的方式拆解电机控制的底层逻辑,帮你从“看不懂电路图”到“能调个简单电机”。 电机控制不是“大神专属”,只要掌握“电生磁、磁生力”的底层逻辑,加上动手实践,小白也能快速入门。这篇博客会陪你从“看电机转”到“让电机听话”,把复杂的控制原理变成能上手玩的“小实验”。准备好你的面包板和电机,我们一起开启“电控之旅”吧!

汽车电子软件领域知识分享 5605

SpringBoot中@Enable*与@Import注解

1 背景介绍 我们在开发SpringBoot项目时会引用很多功能包,常会看到@Enable*注解[1]。例如使用Spring StateMachine中@EnableStateMachine注解启用状态机相关能力。相关能力就是通过开发一些类,生成实例来提供能力。例如状态机配置选择,状态机配置等。接着查看@Enable*注解通常会带有@Import注解。通过@Import注解实现了@Enable*的...

Revivedsun的专栏 1063

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Spring Boot 入门(2){springBootEnable注解分析,EnableAutoConfiguration注解分析,SpringBoot 事件监听}

Spring Boot@Enable*注解工作原理 表示启用某一项。 @EnableConfigurationProperties //启用某一个特性,可以吧配置文件的属性注入到bean中 配合 @ConfigurationProperties使用 @Async @EnableAsync //搭配使用 @EnableAsync 表示配置文件启用异步执行 ;@Async表示该类支持异步 原理: @...

Rage your dream 363

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

springboot starter工作原理_springboot需要知道的几个点

现在关于springboot的使用可以说是如日中天的程度了,使用springcloud那一套的必须是springboot为基础,使用dubbo的很多伙伴也使用springboot了;所以有必要把springboot的一些知识调进行列一下。入门pom.xml中加入<parent> <groupId>org.springframework.boot</groupId&gt...

weixin_39946327的博客 99

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Spring Boot 学习笔记1——原理入门

spring 官方参考资料:https://spring.io/ 目录 Spring Boot概念 Spring Boot启动流程 自动配置 @Enable*工作原理 Spring Boot外部配置 日志配置 Spring Boot概念 1、Spring Boot是什么 Spring Boot是用来简化Spring应用初始搭建及开发过程的全新框架,它使用“习惯优于配置”的原则...

wudiyong22的专栏 536

学习笔记:JavaEE开发的颠覆者SpringBoot实战(三)spring 高级话题

资源信息都来自网络,本人只是记录作为个人笔记 一. Spring Aware 在实际项目中,你不可避免的要用到spring容器本身的功能资源,这时你的bena必须要意识到spring容器的存在,才能调用spring所提供的资源,这就是所谓的Spring Aware。 spring提供的Aware接口 BeanNameAware 获取容器中的bean BeanFactoryAwar...

java_shm的专栏 283

SpringBoot学习

创建autoconfigure模块创建starter模块,依赖autoconfigure模块autoconfigure模块中初始化对象,并定义META-INF/spring.factories文件指定读取properties内容,便于用户自定义对象创建入参。

tz986548749的博客 429

springboot学习笔记

视频地址:https://www.bilibili.com/video/BV1Lq4y1J77x?from=search&seid=15376935294305848216 一、必备链接 docs:https://docs.spring.io/spring-boot/docs/current/reference/html/ springboot-initializr:https://start.spring.io/ 二、课程内容 1、读取配置文件 单个获取 @Value("${...

zhaoguanghe的博客 258

Spring Boot实战(3) Spring高级话题

1. Spring Aware Spring的依赖注入的最大亮点就是你所有的Bean对Spring容器的存在是没有意识的。即你可以将你的容器替换成别的容器。 实际项目中,不可避免地会用到Spring容器本身的功能资源,这时的Bean必须意识到Spring容器的存在,才能调用Spring所提供的资源,这就是所谓的Spring Aware。 Spring提供的Aware接口如下: ...

debang2014010的专栏 210

Spring Boot定时任务-SpringBoot整合Quartz

如何通过SpringBoot整合Quartz框架,我们首先去创建一个项目,接下来我们需要在pom文件里添加坐标, 我们在使用SpringBoot整合Quartz的时候,需要添加哪些坐标呢,我们来看一下,在这里我们需要添加三个坐标, 第一个是quartz的坐标 <dependency> <groupId>org.quartz-scheduler</groupI...

Leon_Jinhai_Sun的博客 348

1.10.Spring Boot核心注解@Spring常用注解

1.声明bean的注解 @Component 组件,没有明确的角色 @Service 在业务逻辑层使用(service层) @Repository 在数据访问层使用(dao层) @Controller 在展现层使用,控制器的声明(C) 2.注入bean的注解 @Autowired:由Spring提供 @Inject:由JSR-330提供 @Resource:由JSR-250提供 都可以注解在set方法和属性上,推荐注解在属性上(一目了然,少写代码)。 3.java配置类相关注解 @Configuration

weixin_JimZemlin的博客 154

springboot2.x基础教程:JRebel实现SpringBoot热部署

当我们开发SpringBoot过程中通常比较频繁的修改代码,每次都要重启项目等待很长才能生效。Idea的Jrebel插件能够实现修改了代码的某一部分,不需要再次启动程序,随时修改,随时生效。接下来就给大家贴出Idea工具安装、破解JRebel这款神器的详细图文教程。 本文导航Idea配置JrebelIdea安装Jrebel插件破解Jrebel首先本地运行jrebel-crack.jar在Idea的Help菜单中找到JRebel,Activation填入本地生成的破解地址最后最后,还要进行下简单的配置测试.

编程之家出品 756

springboot2.x基础教程:动手制作一个starter包

上一篇博客介绍了springboot自动装配的原理。springboot本身有丰富的spring-boot-starter-xx集成组件,这一篇趁热打铁加深理解,我们利用springboot自动装配的机制,制作一个属于自己的starter包。 制作一个starter包思路 ​ 这一篇博客我制作一个上传图片第三方图床的starter,集成常见的第三方图床sm.ms、imgur、github图床等。 ​ 本教程不会具体的讲解图床上传相关的代码,而是主要分析封装此starter的思路。 首先安装spring.

编程之家出品 721

springboot2.x基础教程:@Scheduled开启定时任务及源码分析

在项目开发过程中,我们经常需要执行具有周期性的任务,通过定时任务可以很好的帮助我们实现。 常见的定时任务有JDK自带的TimeTask,ScheduledExecutorService,第三方的quartz框架,elastic-job等。 今天要给大家介绍的是SpringBoot自带的定时任务框架,通过@Scheduled注解就能很方便的开启一个定时任务。 Spring Schedule框架功能完善,简单易用。对于中小型项目需求,Spring Schedule是完全可以胜任的。 本文导航TimeTask.

编程之家出品 572
上一篇: springboot2.x基础教程:@Async开启异步任务
下一篇: springboot2.x基础教程:过滤器和拦截器详解
程序员众推
博客等级 码龄10年 8粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员众推

谢谢老铁鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值