SpringBoot底层理解

SpringBoot高级 一、SpirngBoot自动化配置原理 1.1 Spring Boot Starter Starter依赖管理机制通常是指Spring Boot项目中的依赖自动配置特性。Spring Boot简化了新项目的初始设置,它通过starter模块(例如spring-boot-st

SpringBoot高级

一、SpirngBoot自动化配置原理

1.1 Spring Boot Starter

Starter依赖管理机制通常是指Spring Boot项目中的依赖自动配置特性。Spring Boot简化了新项目的初始设置,它通过starter模块(例如spring-boot-starter-web、spring-boot-starter-data-jpa等)包含了常用的一些依赖,开发者只需要添加相应的starter到项目中,Spring Boot就会自动配置相关的基础设施和服务。
包括:依赖管理,自动配置

1.1.1 依赖管理机制

  1. 通过依赖 spring-boot-dependencies 搜索 starter- 发现非常多的官方starter,并且已经帮助我们管理好了版本。有了这些starter我们就不需要再去一个个的找相关的依赖,相当于一个打包好的开发依赖套餐。
  2. 项目中使用直接引入对应的 starter 即可,这个场景下需要的依赖就会自动导入到项目中,简化了繁琐的依赖。
  3. 如果需要修改版本可以有两种方式:
  • 重写maven属性,在<properties>中重写相关属性
  • 使用Maven依赖管理的就近原则,直接在<dependency>重新导入依赖书写version
  1. 引入 starter 不仅仅是帮助我们管理了依赖,还帮我做了很多的默认的配置信息,简化了大量的配置,使用更加的简单。
  2. 所有的场景启动器的底层都依赖 spring-boot-starter

在POM中修改版本两种方式:

//重写maven属性
<properties>
    <java.version>1.8</java.version>
    <mysql.version>5.1.45</mysql.version>
</properties>

//使用Maven依赖管理的就近原则
<dependencys>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</groupId>
        <version>5.1.45</version>
    </dependency>
</dependencys>
  • 引入官方starter依赖默认都可以不写版本
  • 如果配置满足您当前开发需要,则默认配置即可

1.1.2 自动配置

Starter自动配置是Spring Boot框架提供的一种简化配置的方式。它允许开发者通过添加依赖于特定的starter模块(如spring-boot-starter-web、spring-boot-starter-data-jpa等),Spring Boot会自动配置相关的基础设施和服务,例如设置数据库连接、启用Web服务器、整合各种第三方库等。这种方式极大地减少了手动配置的工作量,使得快速搭建基础功能变得更加容易。每个starter都专注于某个特定的功能领域,让你能够快速启动并运行一个完整的应用。
例如: web 开发场景启动器依赖

<!--web开发的起步依赖   场景启动器依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>

帮助我们做了以下自动化配置:

  1. 依赖版本和依赖什么jar都不需要开发者关注
  2. 自动化配置
  • 自动配好SpringMVC
    • 引入SpringMVC全套组件
    • 自动配好SpringMVC常用组件(三大组件:处理器映射器HandlerMapping,视图解析器,处理器映射器,文件上传等)
  • 自动配好Web常见功能,如:字符编码问题,静态资源管理
  1. 自动配好Tomcat

1.2 @Configuration配置注解

  • @Configuration注解的作用是替代原始 spring配置文件功能
  • SpringBoot 提供一个注解和当前注解功能一样:@SpringBootConfiguration

1.2.1 proxyBeanMethods参数

proxyBeanMethods:代理bean的方法属性(since spring 5.2以后)
功能:

  • proxyBeanMethods = true:Full模式,保证每个@Bean方法被调用多少次返回的组件都是单实例的
  • proxyBeanMethods = false:Lite模式,每个@Bean方法被调用多少次返回的组件都是新创建的

注意:

  • 组件依赖必须使用Full模式默认。
  • Full模式每次都会检查bean,效率较Lite模式慢

1.3 @Import注解

@Import提供4种用法:

  1. 导入Bean
  2. 导入配置类
  3. 导入 ImportSelector 实现类。一般用于加载配置文件中的类Z
  4. 导入 ImportBeanDefinitionRegistrar 实现类

1.3.1 导入 ImportSelector

导入 ImportSelector 实现类。实现selectImprotes方法,返回值为需要加载容器的全路径数组,一般用于加载配置文件中的类
MyImportSelector这个类本身是不会进入容器

public class MyImportSelector implements ImportSerlector{
  public Stirng[] selectImprots(AnnotationMetadata improtingClasssMetadata){
    return new String[]{"comitheima.config.Account"};
    }
}

//在配置类中import注解加载
@Configuratino
@Import(MyImportSelector.class)
public class MyConfig{}

1.3.2 导入 ImportBeanDefinitionRegistrar

导入 ImportBeanDefinitionRegistrar 实现类
BeanDefinitions意思是Bean的定义

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
 
  /**
     * @param importingClassMetadata 导入类的元注解信息
     * @param registry Bean注册表
     */
  @Override
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
    registry.registerBeanDefinition("user", beanDefinition);
  }
}

1.4 @Conditional衍生条件装配

条件装配,满足Conditional指定的条件,则进行组件注入,初始化Bean对象到IOC容器
image-iqbb.png
image-evwa.png
@ConditionalOnXXX 注解存在的意义是:满足条件当前类或者Bean才有效,按需导入。
注意:也可以添加到 类上, 满足条件则类及类中的对象生效。

1.5 @ConfigurationProperties配置绑定

获取配置属性或者是配置文件指定前缀的属性信息,并且初始化Bean对象到 IOC 容器。
将来的配置我们可以放在配置文件中,通过这个注解来读取并封装成对象
就可以直接在配置文件中直接注入属性。

1.6 @SpringBootApplication入口分析

SpringBoot是一个组合注解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguartion
  • @ComponentScan
  1. @SpringBootConfiguration注解作用
    • @SpringBootConfiguration是对@Configuration注解的包装,proxyBeanMethods 默认配置 true, full模式(单例Bean)
    • 标识是一个配置类,所以 引导类也是配置类
  2. @ComponentScan注解作用
    • 组件扫描,默认扫描的规则 引导类所在的包及其子包所有带注解的类
  3. @EnableAutoConfiguration自动配置注解
    • @EnableAutoConfiguration是一个组合注解
      • @AutoConfigurationPackage作用:利用Registrar给容器中导入一系列组件,默认情况下 将引导类的所有包及其子包的组件导入进来
      • @Import(AutoConfigurationImportSelector.class)注解作用

1.6.1 @Import(AutoConfigurationImportSelector.class)注解作用

作用:是利用selectImports方法中的 getAutoConfigurationEntry 方法给容器中批量导入相关组件

调用流程分析:

  1. 调用AutoConfigurationImportSelector类中的selectImports方法
  2. 调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类
  3. 利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader)得到所有的组件
  4. 从META-INF/spring.factories位置来加载一个文件。
    默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件

1.7 SpringBoot自动化配置流程总结

  • 程序启动找到自动化配置包下 META-INF/spring.factories 的EnableAutoConfiguration
  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
  • 每个自动配置类按照条件进行生效。
  • 生效的配置类就会给容器中装配很多组件
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置
    • 用户直接自己@Bean替换底层的组件
    • 用户去看这个组件是获取的配置文件什么值就去修改。
      image-wiwi.png

开发人员使用步骤总结:

  • 引入场景依赖
  • 查看自动配置了哪些(选做)
    • 自己分析,引入场景对应的自动配置一般都生效了
    • 配置文件中debug=true开启自动配置报告。Negative(不生效)\Positive(生效)
  • 自己分析是否需要修改
  • 参照文档修改配置项,xxxxProperties绑定了配置文件的哪些。
    • 自定义加入或者替换组件,@Bean、@Component等

二、SpringBoot健康监控

每一个微服务在云上部署以后,我们都需要对其进行监控、追踪、审计、控制等。SpringBoot就抽取了Actuator场景,使得我们每个微服务快速引用即可获得生产级别的应用监控、审计等功能。
使用spring-boot-starter-actuator来查看SpringBoot监控。

  1. 引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  1. 启动项目,访问 http://localhost:80/actuator
  2. 配置starter的相关配置--暴露所有监控信息为HTTP
management:
  endpoints:
    enabled-by-default: true #暴露所有端点信息
    web:
      exposure:
        include: '*'  #以web方式暴露
 
  endpoint:
    health:
      enabled: true   # 开启健康检查详细信息
      show-details: always

2.1 监控-Admin可视化

SpringBoot Admin 有两个角色,客户端(Client)和服务端(Server)。

Spring Boot Admin为注册的应用程序提供以下功能:

  • 显示健康状况
  • 显示详细信息,例如
  • JVM和内存指标
  • micrometer.io指标
  • 数据源指标
  • 缓存指标
  • 显示内部信息
  • 关注并下载日志文件
  • 查看JVM系统和环境属性
  • 查看Spring Boot配置属性
  • 支持Spring Cloud的可发布/ env-和// refresh-endpoint
  • 轻松的日志级别管理
  • 与JMX-beans交互
  • 查看线程转储
  • 查看http-traces
  • 查看审核事件
  • 查看http端点
  • 查看预定的任务
  • 查看和删除活动会话(使用spring-session)
  • 查看Flyway / Liquibase数据库迁移
  • 下载heapdump
  • 状态更改通知(通过电子邮件,Slack,Hipchat等)
  • 状态更改的事件日志(非持久性)

2.1.1 快速搭建

快速入门:Spring Boot Admin Reference Guide
搭建Server端:

  1. 创建 admin_server 模块,引入依赖
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.10.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
 
<dependencies>
    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-starter-server</artifactId>
        <version>2.3.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
 
</dependencies>
  1. 开启注解支持
@SpringBootApplication
@EnableAdminServer
public class AdminApplication {
    public static void main(String[] args) {
        SpringApplication.run(AdminApplication.class, args);
    }
}

注意端口冲突

搭建Client端:

  1. 在任意服务里面引入依赖
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>2.3.1</version>
</dependency>
  1. 配置文件
  # 执行admin.server地址
spring:   
  boot:
    admin:
      client:
        url: http://localhost:9999  # admin 服务地址
        instance:
          prefer-ip: true   # 显示IP
  application:
    name: boot_data  # 项目名称
    
management:
  endpoints:
    enabled-by-default: true #暴露所有端点信息
    web:
      exposure:
        include: '*'  #以web方式暴露
 
  endpoint:
    health:
      enabled: true   # 开启健康检查详细信息
      show-details: always
  1. 启动服务,访问admin Server http://localhost:端口号/

三、LomBok

  1. pom依赖
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
  1. 实体类
@Data  // set/get/tostring ....
@AllArgsConstructor  // 全参
@NoArgsConstructor // 无参构造
@ToString // tostring
@Accessors(chain = true)  // 链式调用
@Builder  // 构建者模式创建对象
@Slf4j  // 日志注解支持
public class User {
 
    private Long id;
    private String userName;
    private Integer sex;
    private LocalDate birthday;
    private Date created;
    private Date modified;
 
}

@Builder 构建者模式创建对象,一般与@AllArgsConstructor 全参构造器@NoArgsConstructor 无参构造器一起使用

User user = User.builder().name("222").age(123).build();

@Accessors(chain = true) 链式调用

User user = new User();
user.setName("123").setAge(12);
Comment