Spring boot 特性和自写Reids组件

从MVC到boot

Spring Framework AOP、IOC/DI

Spring 万能胶

如何对配置进行轻量化

思考,MVC项目如何完成一个代码编写

创建一个项目结构(maven/gradle)

spring的依赖,spring mvc 、servlet api的依赖

web.xml, DispatcherServlet

启动一个Spring mVC的配置,Dispatcher-servlet.xml

创建一个Controller 发布一个http请求

发布到jsp/servlet容器

如果要引入mybatis还需要各种各样的配置

Spring的产生

在主容器引导 spring 容器内配置 Web 容器服务

什么是Boot

只要依赖的spring-boot-starter-web的jar,就会自动内置一个tomcat容器(替换)

项目结构

默认提供了配置文件application.properties

starter启动依赖 - 如果是一个webstarter ,默认认为你是去构建一个spring mvc的应用.

EnableAutoConfiguration 自动装配 ?

Starter 启动依赖 依赖于自动装配的技术

Actuator 监控 , 提供了一些endpoint ,http、jmx形式去进行访问, health信息。 metrics 信

息、 。。。

Spring Boot CLI(命令行操作的功能, groovy脚本) 客户端, groovy

微服务和BOOT

那为什么Spring Cloud会采用Spring Boot来作为基础框架呢?原因很简单

  1. Spring Cloud它是关注服务治理领域的解决方案,而服务治理是依托于服务架构之上,所以它仍然

需要一个承载框架

  1. Spring Boot 可以简单认为它是一套快速配置Spring应用的脚手架,它可以快速开发单个微服务

所以spring cloud的版本和spring boot版本的兼容性有很大关联

Boot的发展进程

自动装配发展

基于注解发展

舍弃xml繁琐

Spring 注解驱动发展历史

1.0

在SpringFramework1.x时代,其中在1.2.0是这个时代的分水岭,当时Java5刚刚发布,业界正兴起了使

用Annotation的技术风,Spring Framework自然也提供了支持,比如当时已经支持了@Transactional

等注解,但是这个时候,XML配置方式还是唯一选择。

<bean name="" class=""/>

Spring 2.x阶段
  • 新增注解

    • @Required:检查属性是否完成注入
    • @Repository:标记数据访问层(DAO)
    • @Aspect:AOP 切面注解
  • XML 能力大幅增强

    • 支持可扩展 XML 命名空间
    • 第三方框架(如 Dubbo)可以通过扩展 Spring XML 标签无缝集成
    • XML 依然是核心配置方式

Spring 2.5 版本(2.x 时代的分水岭

  1. 新增核心注解

@Autowired:依赖注入

@Qualifier:依赖查找 / 指定注入 Bean 名称

@Component:通用组件标记

@Service:业务逻辑层(Service)

@Controller:Web 控制层

@RequestMapping:SpringMVC 请求映射

关键:依然是 XML 配置驱动 虽然有了大量注解,但必须依靠 XML 才能生效

复制代码
<!-- 开启注解处理器 → 让 @Autowired 等注解生效 -->
<context:annotation-config/>

<!-- 扫描包下的注解类,自动注册为Bean -->
<context:component-scan base-package="com.example"/>
  • <context:annotation-config/>:注册注解处理器,使注解生效
  • <context:component-scan/>:扫描包路径,把@Component/@Service/@Controller类自动注册成 Spring Bean
  • 替代了一部分手写的
3.0

使用 AnnotationConfigApplicationContext 加载

去除了xml的方式

纯注解 + 配置类 = 彻底抛弃 XML

@Configuration 去xml化

核心目的是:把bean对象如何更加便捷的方式去加载到Spring IOC容器中

Component-Scan - @Service @Repository @Controller

Import

Enable模块驱动 启动自动配置

Spring3.x版本中,集成Redis或者mybatis

创建配置类(替代 XML 文件)

用 @Bean 声明第三方组件的 Bean(替代 XML 里的 <bean> 标签)

用 @EnableXxx 启动模块,自动装配相关组件(底层也是注册处理器 / BeanPostProcessor)

自动装配思想

ScheduledAnnotationBeanPostProcessor,对应的是 @EnableScheduling 注解的底层实现

复制代码
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class SchedulingConfiguration {

    @Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
        return new ScheduledAnnotationBeanPostProcessor();
    }
}
  • @EnableScheduling 注解会导入这个 SchedulingConfiguration 配置类,自动注册 ScheduledAnnotationBeanPostProcessor
  • 这个处理器的作用,就是扫描并处理所有 @Scheduled 注解,让定时任务生效。
  • 这也是所有 @EnableXxx 注解的通用逻辑:通过导入配置类,自动注册相关的处理器 / Bean,完成模块的初始化和装配

先注册后置处理器 → 再统一扫描、解析、生效注解

复制代码
@EnableScheduling

@Import(SchedulingConfiguration.class)

作用:让 Spring 提前加载这个配置类

复制代码
@Bean(
    name = {"org.springframework.context.annotation.internalScheduledAnnotationProcessor"}
)
@Role(2)
public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
    return new ScheduledAnnotationBeanPostProcessor();
}

前置核心:把 "注解处理器" 提前放入 Spring 容器

ScheduledAnnotationBeanPostProcessor 是一个 BeanPostProcessor

它的工作时机:Bean 初始化之后 → 后置处理阶段

它干两件事:

  1. 扫描所有 Bean 上的 @Scheduled 注解
  2. 把这些方法注册成定时任务

这就是:先注册处理器(前置) → 后处理注解(后置)

一个注解自动注册全套组件 → 自动装配雏形

你不需要知道:

  • 谁在解析 @Scheduled
  • 谁在注册任务
  • 任务执行器是谁

只要开注解,就能用 → 这就是自动装配

  1. 模块化装配:@EnableXXX = 启动一个模块
  • @EnableScheduling → 开启定时任务
  • @EnableAsync → 开启异步
  • @EnableTransactionManagement → 开启事务
  • @EnableCaching → 开启缓存

模式完全统一:一个注解启动一套功能 = 自动装配的标准模型

ScheduledAnnotationBeanPostProcessor 是 Spring 定时任务的核心中枢:它是一个 Bean 后置处理器,在 Bean 初始化之后扫描 @Scheduled 注解,解析任务规则,注册并管理所有定时任务,在容器初始化完成后统一启动。它通过后置处理 + 注解驱动 + 自动注册,实现了完全无配置、开箱即用的定时任务能力,是 Spring 自动装配思想最早期、最标准的实践模型。

@EnableScheduling→ 注册 ScheduledAnnotationBeanPostProcessor → 后置处理扫描 @Scheduled→ 解析、注册任务→ 容器启动 → 任务自动执行

4.0

Spring 4.x @Conditional(条件装配)

@Conditional 是 Spring 4.0 引入的条件开关注解 ,核心是在 Bean 注册前做条件判断 ,满足才注册、不满足直接跳过;它把 Spring 3.x 的 "注解驱动" 推进到按需驱动 ,是 Spring Boot 自动配置的底层基石

java 复制代码
// 自定义条件:Linux系统
public class LinuxCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return context.getEnvironment().getProperty("os.name").toLowerCase().contains("linux");
    }
}

// 配置类:仅Linux环境才注册LinuxService
@Configuration
@Conditional(LinuxCondition.class)
public class AppConfig {
    @Bean
    public LinuxService linuxService() { return new LinuxService(); }
}
5.0

@Indexed ------ 给组件扫描做 "索引",大幅提速

@Indexed 是 Spring 5.0 推出的「编译时组件索引」,用来解决 Spring 项目变大后,启动时 component-scan 扫描太慢的问题。

它的核心思想:不再启动时遍历所有 class 文件 → 编译时就生成索引 → 启动直接读索引 → 极快加载 Bean

  1. 你写代码

java

运行

复制代码
@Service
public class UserService {}
  1. 编译阶段(还没运行)@Indexed 扫描到这个类有组件注解自动写入文件META-INF/spring/components.idx内容:

plaintext

复制代码
com.xxx.UserService=org.springframework.stereotype.Service
  1. 项目启动Spring 不再全盘扫描 class直接读取这个索引文件瞬间就把 UserService 注册进 IOC 容器

原理探究

如图,我们的Redis是零配置装载的,按照思路。要么我们写BEan要么框架写BEan

已知是框架写Bean,那么需要注册哪些Bean,框架怎么知道呢

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

由依赖来往里写入

spring-boot-autoconfigure-2.4.3.jar 写入又或者boot扫描,写入加入

java 复制代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.boot.autoconfigure.data.redis;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
    public RedisAutoConfiguration() {
    }

    @Bean
    @ConditionalOnMissingBean(
        name = {"redisTemplate"}
    )
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}
复制代码
Import页导入了需要的
复制代码
@SpringBootApplication(scanBasePackages = "com.rabbiter")
复制代码
@EnableAutoConfiguration
复制代码
@Import({AutoConfigurationImportSelector.class})

AutoConfigurationImportSelector

这段代码 只干一件事

去 spring.factories 里,把所有 EnableAutoConfiguration 的类读出来!

把 RedisAutoConfiguration 从 spring.factories 里读出来,交给 Spring 去注册 Bean!

java 复制代码
protected List<String> getCandidateConfigurations(...) {

    // 1. 去读 spring.factories 文件
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
        this.getSpringFactoriesLoaderFactoryClass(), 
        this.getBeanClassLoader()
    );

    // 2. 如果没读到,直接报错:找不到自动配置
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories...");

    // 3. 返回所有读到的配置类(包括 Redis!)
    return configurations;
}

去所有 jar 包里读 META-INF/spring.factories 文件, 把所有自动配置类的名字全部读取出来!

  • 你启动项目
  • 执行这个方法
  • 读取 spring.factories
  • 拿到 RedisAutoConfiguration
  • Spring 自动注册 RedisTemplate
  • 你直接 @Autowired

自写探究

一个模块同时包含:

  • 自动配置
  • 配置属性
  • 核心功能
  • starter 依赖

src

├── main

│ ├── java

│ │ └── com/demo/redis

│ │ ├── autoconfig

│ │ │ └── DemoRedisAutoConfiguration.java

│ │ ├── properties

│ │ │ └── DemoRedisProperties.java

│ │ ├── core

│ │ │ └── DemoRedisClient.java

│ │ └── annotation

│ └── resources

│ └── META-INF

│ └── spring

│ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports

@EnableAutoConfiguration

读取 spring.factories

加载 RedissonAutoConfiguration

创建 RedissonClient

放入 IOC

用户直接注入

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter</artifactId>

<version>2.3.1.RELEASE</version>

<optional>true</optional>

</dependency>

依赖 作用
spring-core Spring核心
spring-context IOC容器
spring-beans Bean管理
spring-aop AOP
spring-expression SpEL
logback 日志

<dependency>

<groupId>org.redisson</groupId>

<artifactId>redisson</artifactId>

<version>3.13.1</version>

</dependency>

复制代码
复制代码
真正的 Redis 客户端
功能
分布式锁 RLock
延迟队列 RDelayedQueue
阻塞队列 RBlockingQueue
Map缓存 RMap
Set缓存 RSet
原子类 RAtomicLong
限流器 RRateLimiter
布隆过滤器 RBloomFilter
读写锁 RReadWriteLock

spring-boot-configuration-processor

复制代码
复制代码
生成配置提示元数据

spring-boot-starter

提供自动配置能力

redisson

提供Redis客户端能力

configuration-processor

提供IDEA配置提示c

java 复制代码
package com.gupaoedu.redisson;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 咕泡学院,只为更好的你
 * 咕泡学院-Mic: 2227324689
 * http://www.gupaoedu.com
 *
 * @author cxyck*/

@ConditionalOnClass(Redisson.class) //条件装配
@EnableConfigurationProperties(RedissonProperties.class)
@Configuration
public class RedissonAutoConfiguration {

    @Bean
    RedissonClient redissonClient(RedissonProperties redissonProperties){
        Config config = new Config();
        String prefix="redis://";

        config.useSingleServer().
                setAddress(prefix+redissonProperties.getHost()+":"+redissonProperties.getPort()).
                setConnectTimeout(6000);

        return Redisson.create(config);
    }
}
java 复制代码
package com.gupaoedu.redisson;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author cxyck
 */
@ConfigurationProperties(prefix = "gp.redisson")
public class RedissonProperties {

    /**
     * Redis地址
     */
    private String host = "127.0.0.1";

    /**
     * Redis端口
     */
    private Integer port = 6379;

    /**
     * Redis密码
     */
    private String password;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
java 复制代码
{
  "properties": [
    {
      "name": "gp.redisson.host",
      "type": "java.lang.String",
      "description": "redis的服务器地址",
      "defaultValue": "localhost"
    },{
      "name": "gp.redisson.port",
      "type": "java.lang.Integer",
      "description": "redis服务器的端口",
      "defaultValue": 6379
    }
  ]

}
java 复制代码
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.gupaoedu.redisson.RedissonAutoConfiguration
相关推荐
蝎子莱莱爱打怪6 小时前
👍🏻👍🏻6年381颗芯片+韬定律,华为重新定义半导体,为什么还有人喷???
后端·面试·程序员
极光代码工作室6 小时前
基于SpringBoot的课程管理系统
java·springboot·web开发·后端开发
JustNow_Man7 小时前
【opencode】安装使用daytona沙箱插件
android·java·javascript
武子康7 小时前
Java-05 深入浅出 MyBatis动态SQL与参数拼接完全指南
java·spring boot·后端
Kir1to7 小时前
RabbitMQ消息可靠性三板斧
后端
过期动态7 小时前
【LeetCode 热题 100】字母异位分组
java·算法·leetcode·职场和发展·哈希算法
辰海Coding7 小时前
MiniSpring框架学习-为什么一个请求访问 /helloworld,最后能调用到某个 Controller 方法?原始 MVC实现
java·学习·程序人生·spring·mvc
ServBay7 小时前
Google I/O 2026 Antigravity 更新与 SDK
后端·ai编程·google io
驭渊的小故事7 小时前
多线程01(线程状态和线程的sleep,线程终止(Interrupt)的小关联)
java·jvm·算法