一键开启!Spring Boot 的这些「魔法开关」@Enable,你用对了吗?

看Spring源码不得不会的@Enable模块驱动实现原理讲解 这篇文章我想和你聊一聊 spring的@Enable模块驱动的实现原理。在我们平时使用spring的过程中,如果想要加个定时任务的功能,那么就需要加注解@EnableScheduling,如果想使用异步的功能,那就要加@EnableScheduling注解,其实这类注解就是属于@Enable模块。模块是指具备相同领域的功能组件集合,组合所形成一个独立的单元。比如Web MVC模块、AspectJ代理模块Caching缓存模块,JMX(Java管理扩展)、Async异步处理模块等。所谓模块装配,简而言之就是, 阅读详情

01 引言

在我们日常开发中,我们经常会引入第三方框架。使用的时候需要我们在启动类上增加@Enable开头的注解,以标记当前服务或者插件的启用。如:

  • @EnableRetry
  • @EnableScheduling
  • @EnableDubboConfig
  • @EnableAsync
  • …

它们就像一个个精巧的“开关”,轻轻一拨,便能将复杂的功能模块集成到应用中。

这些开关注解里面做了什么东西呢?我们一起一探究竟!

02 核心理念

Spring Boot的核心设计理念是“约定优于配置”,旨在减少开发者在XML和样板代码上的负担,让开发者能够快速构建生产级的应用。

每个开关都提供了一整套默认的、经过实践检验的配置。例如,@EnableRetry默认会使用SimpleRetryPolicy和FixedDelayBackOffPolicy。开发者无需配置任何参数即可使用这些合理的默认值。当有特殊需求时(如更改重试次数、延迟时间),又可以通过注解的参数或配置属性(application.properties)进行自定义,完美平衡了开箱即用和灵活性。

开关的设计是细粒度的资源控制。正如spring-boot-dependencies一样,管理所有的的依赖,但并不会直接引入,需要开发者按需引入,否则项目的jar包就是很大。而开关的设计,则是要么控制资源是否需要加载到Spring容器中,如果不启动开关,资源就不会被Spring容器加载,启动之后,才会加载。这样可以防止无关的资源占用Spring容器的资源。

03 案例源码分析

这些「开关」并非魔法,其背后是Spring框架强大的**@Import注解和导入选择器(ImportSelector)**、配置类(Configuration) 机制。

3.1 @EnableRetry

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@EnableAspectJAutoProxy(proxyTargetClass = false)
@Import(RetryConfiguration.class)
@Documented
public @interface EnableRetry {
    
    @AliasFor(annotation = EnableAspectJAutoProxy.class)
	boolean proxyTargetClass() default false;

	int order() default Ordered.LOWEST_PRECEDENCE - 1;  
}

@EnableRetry本身只是一个标记。其核心是通过@Import(RetryConfiguration.class)导入了另一个配置类。

我们先看一下org.springframework.retry.annotation.RetryConfiguration的继承关系

我们可以看到,该类实现了众多Spring的扩展接口,如BeanFactoryAware、InitializingBean、SmartInitializingSingleton、ImportAware等。

关键代码块:

我们知道afterPropertiesSet是InitializingBean接口的方法,在初始化Bean对象之后自动执行,也就是说会自动执行到此处。

画框的地方,正式通过@Retryable注解构造AOP的切点和通知等。这样一起项目启动之后,当调用该方法时,代理会介入执行,按照预设的重试策略(Retry Policy)和回退策略(Backoff Policy)进行重试。

3.2 @EnableScheduling

@EnableScheduling使用用来开启定时任务的开关。

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

}

@EnableScheduling里面连属性都没有,同样依赖@import导入的类(SchedulingConfiguration.class)

内部只是实例化了一个Bean,并交给Spring容器管理。看看Bean对象的继承关系

ScheduledAnnotationBeanPostProcessor

同样实现了Spring的诸多扩展接口。

实例化后,注册ScheduledTaskRegistrar

然后调用afterPropertiesSet()方法,来增加调度任务。

3.3 手搓Bean初始化耗时开关

核心代码

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    Map<String, Long> map = new ConcurrentHashMap<>();

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        map.put(beanName, System.nanoTime());
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        long end = System.nanoTime();
        System.out.println("初始化Bean【" + beanName + "】,耗时:" + (end - map.get(beanName)) + "ns");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

由于Bean的位置不在启动类的扫描范围内,所以该类便不会加载。我们通过开关通知启动类是否需要加载。

开关类:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(MyBeanPostProcessor.class)
public @interface EnableStatTime {
}

启动类增加开关

结果

04 优势

这种“开关”式设计为Spring Boot生态系统带来了巨大优势:

  • 低侵入性:功能模块与业务代码解耦,添加或移除功能只需操作一个注解,无需修改核心业务逻辑。
  • 降低使用门槛:开发者无需深入理解模块的内部实现细节,只需知道注解的存在和基本用法即可快速集成高级功能。
  • 可维护性强:每个功能的配置和装配逻辑被封装在独立的@Configuration类或ImportSelector中,结构清晰,易于维护和扩展。
  • 一致性体验:无论是什么功能,其启用方式都是统一的@Enable*模式,降低了学习成本,提供了优雅一致的用户体验。

05 小结

Spring Boot中的@Enable*系列注解绝非简单的语法糖,它们是Spring框架“容器化”和“模块化”设计思想的集大成者。

通过声明式编程和自动装配机制,它们将复杂的技术实现细节完美地隐藏在一个个简洁的注解之后,让开发者能够专注于业务逻辑本身,从而真正实现了Spring Boot“快速开发”和“轻松集成”的承诺。

理解和掌握这些“开关”背后的设计哲学,有助于我们更好地使用Spring Boot,乃至设计和实现自己的 Starter 与自动配置模块。

springboot定时任务的动态开启关闭 SpringBoot实现定时任务的动态开启关闭,如有疑问联系wx: hsj179540 立即下载

相关推荐

AI辅助专利撰写实战:用Codex 30分钟生成发明专利初稿

这次我们来看一个用 Codex 从零开始撰写发明专利的实战项目。对于技术研发人员、产品经理或初创团队来说,专利申请是保护创新成果、构建技术壁垒的关键一步。然而,撰写一份高质量的专利申请书,尤其是权利要求书和说明书,往往需要专业的法律和技术语言,耗时耗力。这个项目演示了如何利用 AI 工具 Codex,在短时间内生成一份结构完整、逻辑清晰、具备授权潜力的专利申请文件初稿。 整个过程的核心不是让 AI 完全替代专利代理人,而是将其作为强大的“技术翻译”和“内容生成”助手。它能将你的技术构思、流程图、核心算法或产

weixin_32181267的博客 421

SpringRetry重试机制

前言 Spring实现了一套重试机制,功能简单实用。Spring Retry是从Spring Batch 2.2.0版本中独立出来,变成了Spring Retry模块。,已经广泛应用于Spring Batch,Spring Integration, Spring for Apache Hadoop等Spring项目。 使用Spring Retry (一)Maven依赖 <!--...

Lyzxii 4971

[TC3XX]AURIX TC3XX系列之启动流程

本文介绍了微控制器(MCU)启动过程中固件(Firmware)和启动软件(SSW)的工作原理。MCU上电复位后,硬件完成初始化,BootROM中的固件开始执行,进行参数加载、模式选择等操作。SSW作为第一个执行的软件,负责时钟配置、安全检查、多核管理及启动模式选择,最终跳转至用户代码。启动模式包括内部Flash启动、Bootloader模式(通过ASC或CAN接口)和备用启动模式(ABM),具体由复位类型、引脚配置和UCB设置决定。文章特别指出英飞凌TC3xx系列芯片中固件不可修改,只能通过配置参数定制启动

redparrot2008的博客 1423

@EnableRetry、@Retryable、@Recover 详解

是 Spring Retry 提供的核心注解,用于在 Spring 应用中轻松实现自动重试功能。,可以轻松实现自动重试和降级处理,增强系统的可靠性和容错性。

Gemini1995的博客 1349

【2026年华为暑期实习(非AI方向(通软&嵌软&测试&算法&数据科学))-4月8日-第一题- 包裹的编码】(题目+思路+Java&C++&Python解析+在线测试)

摘要:该问题要求将给定的十进制整数N转换为混合进制编码字符串,并处理回文检测。首先根据N的符号位确定编码首位(0或1),然后按输入的进制序列依次对N的绝对值进行取余和整除操作,得到编码数组。将数组元素转换为字母后生成字符串,若字符串为回文则添加"(palindrome)"后缀;否则输出最长回文子串(字典序最小)。算法采用中心扩展法检测回文,时间复杂度为O(L²),空间复杂度为O(L),其中L为字符串长度。

m0_73659489的博客 130

AutoSAR系列讲解(入门篇)4.6-BSW的Watchdog功能

BSW的看门狗功能

雪云飞星的博客 1万+

Spring重试功能@Retryable

@Retryable源码解析

明豆的博客 2577

Python实战日志_P4_图书馆Web API服务

目标:使用Flask将图书馆系统升级为RESTful API服务,掌握Web开发基础难度:⭐⭐⭐⭐☆预计学习时间:75分钟前置要求:已完成第3篇《个人图书馆管理系统》

qq_39436086的博客 84

@EnableRetry(proxyTargetClass = true) . spring-retry概念和基本用法 spring-retry @Recover不执行

准备好好看看一下spring-cloud的源码,把其中实现的原理搞清楚,而不是仅仅会配几个注解,会配几个参数,把“微服务”框架搭建起来。在查看其中pom的的依赖关系时,发现spring-cloud对于spring不仅仅是bean,aop,context等,居然spring-cloud-commons依赖了一个spring-retry的东西。 官方定义: This project provid...

lifewinnerforever的博客 9436

5大绝招破解.NET Core本地IP访问难题——为什么你的调试总卡在localhost?

摘要: 本文详解5种本地IP访问.NET Core应用的方法,涵盖基础IP绑定(0.0.0.0)、防火墙配置、IIS Express优化、远程调试及ngrok内网穿透。关键步骤包括修改launchSettings.json、PowerShell授权端口、SSH远程调试和ngrok外网映射,并提示常见陷阱(如未绑定IP、防火墙拦截)。通过“魔法法则”组合,可实现局域网/外网高效访问,适用于开发测试场景。 (字数:148)

java专栏 956

【知识分享】IBIS 建模指南 03

本文介绍了差分缓冲器的数据提取方法,重点分析了差分系统与单端系统的核心差异。文章详细阐述了差分接收机和驱动器的结构特点、工作原理及建模方法,指出全差分结构具有优异的电源噪声抑制能力。针对IBIS建模规范,作者提出了三维I-V曲面数据提取技术,并介绍了共模/差模电流分离、片上端接处理以及V-T表生成的解决方案。文章还探讨了差分电容(C_diff)的测量方法和数据简化策略,为复杂差分缓冲器的精确建模提供了系统化的技术路径。

一只豌豆象的博客 1282

Spring retry(二)- 源码解析-启动装配篇 @EnableRetry

我们快速介绍了下spring-retry的使用技巧,本篇我们将会剖析源码去学习。

Viogs的专栏 686

使用plot函数可视化F分布累积分布函数数据(R语言)

在上面的代码中,我们使用了seq()函数来生成从0到5之间,以0.1为步长的一组F值。然后,我们指定了分子自由度为3,分母自由度为8,并使用pf()函数计算了对应的F分布CDF值。在本文中,我们将介绍如何使用R语言的plot函数来可视化F分布的累积分布函数(CDF)数据。通过使用plot函数,我们可以直观地了解F分布的累积分布函数,并对F值和对应的累积概率之间的关系有更深入的认识。运行上述代码后,我们将获得一个由F值和对应的累积概率构成的图形,其中x轴表示F值,y轴表示累积概率。

LogicGuruX的博客 503

【手撕 @EnableAsync:揭秘 SpringBoot @Enable 注解的魔法开关】

本文深入解析了SpringBoot中@EnableXXX注解的实现原理,揭示了其本质是通过@Import注解实现功能动态加载的"门面模式"。文章详细介绍了@Import的三种用法:直接导入配置类、使用ImportSelector动态选择和通过ImportBeanDefinitionRegistrar手动注册Bean,并以@EnableAsync为例进行了源码分析。通过实战演示如何自定义@EnableYannLog注解,展示了这种设计模式在实现"按需加载"功能方面的优势

qq_36021478的博客 882

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Spring Boot @Enable*注解源码解析及自定义@Enable*

Spring Boot @Enable注解源码解析及自定义@Enable Spring Boot 一个重要的特点就是自动配置,约定大于配置,几乎所有组件使用其本身约定好的默认配置就可以使用,大大减轻配置的麻烦。其实现自动配置一个方式就是使用@Enable*注解,见其名知其意也,即“使什么可用或开启什么的支持”。 Spring Boot 常用@Enable* 首先来简单介绍一下Spring Boo...

kanlon的博客 4531

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Spring Boot的自动加载与@Enable相关技术

在Java开发中,Spring Boot以其“约定优于配置”的理念,极大地简化了Spring应用的开发和部署过程。其中,Spring Boot的自动配置(Auto-configuration)是其核心特性之一,它通过扫描项目依赖和配置,自动加载并配置相应的Bean。本文将深入探讨Spring Boot的自动加载机制,特别是org.springframework.boot.autoconfigure.AutoConfiguration.imports的作用,并结合@Enable相关技术进行解析。

dcp666的博客 457

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

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

作用:启用某种功能特性的注解 @Enable*注解的种类举例: (1)@EnableConfigurationProperties:用来启用将配置文件属性注入到bean中这一特性,和@ConfigurationProperties注解一起使用。 (2)@EnableAsync启用异步特性,与@Async(相当于对方法或类进行一个标记,具体开启异步任务由TaskExecutor来进行)一起使用 @Async作用 具体作用 Enable*原理一 原理二 import java.util.concurrent.T

qq_40091033的博客 1068

enablediscoveryclient注解的意思_Spring Boot @Enable*注解源码解析及自定义@Enable*

  Spring Boot 一个重要的特点就是自动配置,约定大于配置,几乎所有组件使用其本身约定好的默认配置就可以使用,大大减轻配置的麻烦。其实现自动配置一个方式就是使用@Enable*注解,见其名知其意也,即“使什么可用或开启什么的支持”。Spring Boot 常用@Enable*首先来简单介绍一下Spring Boot 常用的@Enable*注解及其作用吧。@EnableAutoC...

weixin_39907658的博客 5755

Spring Boot 自动配置之@Enable*与@Import注解

原文地址:添加链接描述 SpringBoot 的自动配置如此强大,比如我们经常使用的@Enable* 注解来开启对某方面的支持。那么@Enable* 注解的原理是什么呢? 一、@Enable* 注解与 @Import 注解之间的关系 @Enable* 举例: @EnableScheduling 开启计划任务的支持 @EnableAsync 开启异步方法的支持 @EnableAspectJAutoP...

yxwb1253587469的博客 512

【SpringBoot框架篇】20.自定义@Configuration配置类启用开关

简介 通过@Configuration注解标识的类默认都会被spring加载,但是我们有时候想要通过开关来决定要不要加载,这个时候就需要该博客讲解的内容。 我目前了解的两种实现方式如下 1.自定义@Enable注解 2.通过配置文件配置 自定义@Enable注解 我常用的例如:@EnableCaching(缓存)、@EnableScheduling(定时任务),@EnableJpaAuditing(审计),这类注解就像开关一样,只要在SpringBoot启动类上加这类注解,就能开启相关的功能。 本文以

皓亮君的博客 6024

Spring Boot 手动配置@Enable的秘密

在Spring Boot中,我们会经常遇到@Enable***用来激活我们某一个功能性的模块,通过类注解激活后我们就能使用所激活的配置给我们带来的功能。接下来我们就来探究一下这个@Enable***给我们做了哪些工作,或者我们应该怎么通过自定义的方式开发我们自己的功能模块。 演示环境 IntelliJ IDEA 2018.2.1 (Community Edition) Maven 3.5.4 S...

JeromeSoar的博客 386

Spring-boot|如何自定义@Enable模块装配

背景 在学习SpringBoot的时候,我们会使用到@Enable***注解的地方,使用上也都是加在@Configuration 类注解的类上面,比如: (1)@EnableAutoConfiguration 开启自动扫描装配Bean (2)@EnableScheduling 开启计划任务的支持 (3)@EnableTransactionManagement 开启注解式事务的支持。 (4)@Ena...

dsdj 3670

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

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

AlbenXie的博客 353

Spring Boot 配置(官网文档解读)

本文参考Spring官方,对SpringBoot外部化配置模块进行详细的阐述和总结。旨在为广大学习者和开发者提供一个关于SpringBoot配置模块实用的参考资料。 SpringBoot可以帮助你在不同的环境中使用一套代码。你可以使用各种不同的配置方式,例如Java属性文件、YAML文件、环境变量和命令行参数等。 

wend的博客 2849
上一篇: 接口调用总失败?试试Spring官方重试框架Spring-Retry
下一篇: 从西贝预制菜到Java依赖:我们该如何吃透预制代码?
智_永无止境
博客等级 码龄10年 803粉丝 406原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

智_永无止境

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值