• SpringBoot 核心理论


    1.SpringBoot

    1.1 概念

    SpringBoot是由Pivotal团队在2013年开始研发、2014年4月发布第一个版本的全新开源的轻量级框架。它基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。

    • 设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。
    • 核心:自动配置、基于 约定大于配置 原则。
    • 父依赖维护 SpringBoot 版本号即可
    • 核心注解:@EnableAutoConfiguration

    1.2 核心依赖

    SpringBoot 父依赖为核心依赖,其中默认管理了很多 jar 包的版本,所以我们再根 pom.xml 中如果不需要指定特殊的版本,可不指定 jar 包版本。

    查看核心依赖

    1. 进入 spring-boot-starter-parent
        <parent>
            <groupId>org.springframework.boot</groupId>
            <!-- 跟进 以下目录,查看父依赖的 -->
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.3.1.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
    1. 进入spring-boot-dependencies
    <!-- 再进入   -->
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.3.1.RELEASE</version>
      </parent>
    

    进入 spring-boot-dependencies-2.3.1.RELEASE.pom 文件后,可发现在 propertiesdependencyManagement

    中有很多依赖已经配置并指定版本号好。

    1.3 自动装配(核心)

    SpringBoot 的核心就在于 自动装配

    SpringBoot 自动装配的过程:

    SpringBoot 通过 @EnableAutoConfiguration 注解开启自动装配;加载 spring.factories 中注册的各类 AutoConfiguration;当 AutoConfiguration 类满足 @Conditional 注解中的条件时,则实例化该 AutoConfiguration 类中定义的 Bean,并注入 Spring 容器中。

    @EnableAutoConfiguration

    该注解由 @SpringBootApplication 引入,完成开启自动装配;扫描 autoconfigure jar 包 META-INF 下的 spring.factories 文件,并加载其中注册的 AutoConfigure 类等。

    spring.factories

    配置文件,位于 autoconfigure jar 包 META-INF 目录下;

    AutoConfiguration

    SpringBoot 中的自动配置类,例如 RedisAutoConfiguration 等;其中定义了三方组件集成 Spring 所需的初始化 Bean 和条件

    @Conditional

    SpringBoot 中以 @Conditional 开头的条件注解;AutoConfiguration 需满足其中的条件才可实例化

    image-20200801160902902

    1.3 启动器

    各类三方组件starter

            <!-- Spring web -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!-- Spring Security -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    
            <!-- Spring Boot Mail -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-mail</artifactId>
            </dependency>
    
            <!-- SpringBoot JDBC -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
    
            <!-- 阿里数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.22</version>
            </dependency>
    
            <!-- Mybatis -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.3</version>
            </dependency>
    
            <!-- SpringBoot Redis -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    

    1.4 注解

    SpringBoot 项目创建完会生成 ***Application 启动类;

    package pers.vincent.matrix;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class MatrixApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MatrixApplication.class, args);
        }
    
    }
    

    核心注解@SpringBootApplication

    package org.springframework.boot.autoconfigure;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import org.springframework.beans.factory.support.BeanNameGenerator;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.SpringBootConfiguration;
    import org.springframework.boot.context.TypeExcludeFilter;
    import org.springframework.context.annotation.AnnotationBeanNameGenerator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.core.annotation.AliasFor;
    import org.springframework.data.repository.Repository;
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication {
    
             // 排除指定自动配置类
    	@AliasFor(annotation = EnableAutoConfiguration.class)
    	Class<?>[] exclude() default {};
    
              // 排除指定自动配置名
    	@AliasFor(annotation = EnableAutoConfiguration.class)
    	String[] excludeName() default {};
    
              // 指定扫描的基础包,激活注解组件的初始化
    	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    	String[] scanBasePackages() default {};
           
             // 指定扫描的类,初始化
    	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
    	Class<?>[] scanBasePackageClasses() default {};
    
             // Bean名称生成器
    	@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
    	Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
    
             // 指定是否代理 @Bean 方法
    	@AliasFor(annotation = Configuration.class)
    	boolean proxyBeanMethods() default true;
    
    }
    
    

    结构:

    @SpringBootApplication

    • @SpringBootConfiguration
      • @Configuration
        • @Component
    • @EnableAutoConfiguration
      • @AutoConfigurationPackage
      • @Import(AutoConfigurationImportSelector.class)
    • @ComponentScan
      • @Repeatable(ComponentScans.class)
    @SpringBootConfiguration: SpringBoot 配置
    @Configuration:Spring 配置类
    @Component:组件
        
    @EnableAutoConfiguration:自动配置 (核心注解)
    @AutoConfigurationPackage:自动配置包
    @Import(AutoConfigurationPackages.Registrar.class):自动配置`包注册`
    @Import(AutoConfigurationImportSelector.class): 自动配置导入选择
    @ConditionOnxxxx:如果条件都满足,才能生效
    
    @ComponentScan:扫描    
    

    其余注解:

    • @AliasFor:用于桥接到其他注解,其中的属性指定所桥接的注解类

    @EnableAutoConfiguration

    @Import(AutoConfigurationImportSelector.class)

    AutoConfigurationImportSelector 核心功能解析:

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        
        // 
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        
        // 加载 spring.factories 中的 EnableAutoConfiguration 的配置类
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
        
        // 配置类去重
        configurations = removeDuplicates(configurations);
        
        /// 获得被排除的类集合
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        
        // 检查排除的类是否合法
        checkExcludedClasses(configurations, exclusions);
        
        // 配置类集合中取出被排查的类
        configurations.removeAll(exclusions);
        
        // 过滤自动加载组件
        configurations = getConfigurationClassFilter().filter(configurations);
        
        // 将配置类和排除类 通过事件传入监听器中
        fireAutoConfigurationImportEvents(configurations, exclusions);
        
        // 返回自动配置类全限定名数组
        return new AutoConfigurationEntry(configurations, exclusions);
    }
    
  • 相关阅读:
    Spring MVC程序中得到静态资源文件css,js,图片文件的路径问题总结
    【转】MySQL数据丢失讨论
    【摘】 pt-query-digest工具一解
    【摘】Mysql备份还原数据库之mysqldump实例及参数详细说明
    【原】redis插件安装
    【摘】linux中fstab解说
    【原】mysql慢日志分析
    【原】带宽、流量单位换算关系
    【转】Linux查看内存大小和插槽
    【转】bind
  • 原文地址:https://www.cnblogs.com/blackBlog/p/13451772.html
Copyright © 2020-2023  润新知