• 3springboot执行原理及自动装配原理


    自动配置依赖

    spring boot将各个应用/三方框架 设置成了一个个“场景/启动器”stater,在pom.xml文件里面的spring-boot-starter-parent里面的spring-boot-dependencies依赖里面存储,如下图

    图1按住ctrl,鼠标左击 spring-boot-stater-parent

     

    图2继续按住ctrl键,鼠标左击spring-boot-dependencies进入图3

     

    图3存放着各种版本的依赖,就是springboot不用指定依赖版本的原因。

     

    今天又重新看了pom.xml文件,发现没有了 spring-boot-stater-parent依赖,直接把spring-boot-dependencies依赖放进了pom文件中,如下图:

    spring-boot-dependencies:存储着各种三方框架的启动和一些依赖版本号,比如tomcat,spring boot把所有版本号都写好了,引用就不用指定版本号,而且版本号没有冲突,没有兼容性问题。

    上图依赖有着各种的启动器starter 

    • 启动器:说白了就是springboot的启动场景;
    • 比如spring-boot-starter-web,它就会帮我们自动导入web环境所需的所有依赖。
    • springboot会将所有的功能场景,都变成一个个启动器starter。
    • 我们使用什么功能,就只需要找到对应的启动器就可以了starter(官网有说明)

    我们创建springboot第一个项目时选择了spring web依赖,所以在pom.xml文件里面存在了web工程相关的依赖,这些依赖都是继承的依赖,不用从maven的远程仓库中下载,前提是已经下载过一次

     

    总结:

      pom.xml

        1. spring-boot-dependencies:核心依赖

        2. 我们在写或者引入一些springboot依赖的时候,不需要指定版本,就因为有这些版本仓库(spring-boot-dependencies)。

    Spring boot执行原理:

      主程序

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    //@SpringBootApplication  :标注这个类是一个springboot的应用
    @SpringBootApplication
    public class DemoApplication {
        //将springboot应用启动
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }

      主程序的注解

        @SpringBootApplication 注解

    @SpringBootApplication是spring boot的主配置类,启动全部依赖这个配置类,并且包含两个主要注解:@SpringBootConfiguration@EnableAutoConfiguration ,如下图

       @SpringBootConfiguration注解

          @SpringBootConfiguration注解包含@Configuration,表示“配置类”:

          1.该类是一个配置类  

          2.加了@Configuration注解的类,会自动纳入SpringIoc 容器

    而且@Configuration注解里面还包含着@component注解,所以其实@Configuration和@Component作用相似,在spring里面@component是把该类加进ioc容器中。

     

        @EnableAutoConfiguration:

          @EnableAutoConfiguration自动导入配置

          1. 开启spring boot自动配置

          2.包含两个主要注解:

          @AutoConfigurationPackage:自动获取主类的包名放入到扫描器

          @Import(AutoConfigurationImportSelector.class):选择器,满足条件自动把所依赖的三方依赖包引入。

    宏观来说,@AutoConfigurationPackage就是把你写的代码放进ioc容器中,而@Import(AutoConfigurationImportSelector.class)就是把第三方jar包加入到项目中。

    @AutoConfigurationPackage大概流程

    @AutoConfigurationPackage注解包含了@Import(AutoConfigurationPackages.Registrar.class)如下图:

     

     接下来,我们点进Registrar.class,如下图

    @AutoConfigurationPackage里面的Registrar.class类获取到项目的源数据,然后获取@SpringBootApplication注解(主入口)所在类的包名,获取到包名后自动把该包以及子包添加到注解扫描器里面,这就是为什么第一个springboot程序创建controller测试的时候,要把这个类放在和主入口类的同级/下级路径,因为如果不放这两个路径,Registrar.class类就扫描不打这个新创建的类,就完成不了扫描,也导致了不能自动装配。

     

    @Import(AutoConfigurationImportSelector.class)大概流程:

    通过AutoConfigurationImportSelector.class 把第三方依赖导入项目中,接下来点进AutoConfigurationImportSelector.class看工作流程,我在124行那里打了断点调试,可以看到控制台获取到的数据。

     

     可以发现configurations包含了springboot集成的所有第三方依赖,而这些依赖是通过 getCandidateConfigurations() 方法获取的, 接下来我们继续点击getCandidateConfigurations()方法,看看是如何获取spring boot集成的第三方依赖的,如下图:

      getCandidateConfigurations()方法主要是通过loadFactoryNames获取第三方依赖的,这里再深入loadFactoryNames()方法,查看原理,如下图:

     loadFactoryNames()方法通过loadSpringFactories()获取到文件,该文件就是springboot集成的关于自动配置的第三方依赖jar包,该文件路径如下图:

    idea主界面左边的External Libraries -> Maven: org.springframework.boot : spring-boot-autoconfigure -> META-INF ->  spring.factories

    springboot开启自动装配流程图

     

     补充:spring-boot-autoconfigure-2.0.3.RELEASE.jar包中 包含了 J2EE整合体系中 需要的依赖。

    总结:

       编写项目时,一般会 对自己写的代码  以及 三方依赖 进行配置。但是spring boot可以自动进行配置:

         a:自己写的代码,spring boot通@SpringBootConfiguration自动帮我们配置,加入springIoc容器中;

         b:第三方依赖 通过spring-boot-autoconfigure.RELEASE.jar(位置在Maven Dependencies的第4个)中的META-INF/spring.factories进行声明,然后通过@EnableAutoConfiguration开启使用即可,@EnableAutoConfiguration开启流程上图有。

        c:如何自动装配:

    自动装配了这么多类,这些类是否都开启了?比如写一个helloWorld不需要用到这么多类。

    例子:

    研究org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,(该文件位置: spring-boot-autoconfigure-2.0.3.RELEASE.jar里面的倒数第6个包里面)

     

    通过观察该源码 发现:

    @Configuration:标识此类是一个配置类,将此类纳入springIoc容器

    @EnableConfigurationProperties:让使用 @ConfigurationProperties 注解(这个注解和@component类似)的类生效。

    而另外三个注解是 自动装配的类是否启动触发条件

     

    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)  判断是否为Web程序
    @ConditionalOnClass(CharacterEncodingFilter.class)   判断是否存在指定类
    @ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true) 判断配置文件.properties/.yml是否存在修改编码,如果没有修改编码,则该条件成立

    只有上面三个@ConditionalOn前缀的注解都满足才会执行当前这个类。

    上面三个conditionXX都成立后,执行CharacterEncodingFilter,这个编码拦截器类,获取配置的编码方式,把请求和响应的编码设置为所配置的编码格式

          @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)

          当属性满足要求时,此条件成立  :要求 如果没有配置spring.http.encoding.enabled=xxx, 则成立。

      小结:1、每一个XXXAutoConfiguration ,即第三方自动装配依赖(spring.factories配置文件里),如下图

     都有很多条件@ConditionalOnXxx注解,当这些条件都满足时,则此配置自动装配生效。但是我们可以手工修改 自动装配: Xxx.Properties/.yml文件中的  prefix(前缀).属性名=value ,但是在配置文件中修改后,那么相对应的自动装配的类则不在生效。

    在配置文件中修改配置例如:

     

     

    修改完后,那么这个配置对应的自动装配的类则不在生效。

    2、全局配置文件中的key(key指的是配置的前缀,如:上图的spring.http.encoding,charset是属性名), 来源于某个Properties文件中的 prefix+属性名

    下图是一些conditionXXX条件

     3、如何知道 spring boot开启了哪些自动装配、禁止了哪些自动装配: application.properties中 ,在配置文件里面加上debug=true

     

    运行主类(main)后,控制台显示

     

    Positive matches列表 表示 spring boot自动开启的装配

    Negative matches列表 表示spring boot在此时 并没有启用的自动装配。

    The end.

  • 相关阅读:
    【计算机视觉】OpenCV篇(6)
    【计算机视觉】OpenCV篇(5)
    C++解决头文件相互包含问题的方法
    【计算机视觉】OpenCV篇(4)
    java mysql多次事务 模拟依据汇率转账,并存储转账信息 分层完成 dao层 service 层 client层 连接池使用C3p0 写入库使用DBUtils
    MySQL事务隔离级别 解决并发问题
    在jdbc基础上进阶一小步的C3p0 连接池(DBCP 不能读xml配置文件,已淘汰) 和DBUtils 中两个主要类QueryRunner和ResultSetHandler的使用
    java数据库 JDBC操作MySQL数据库常用API 部门表和员工表 创建表 添加数据 查询数据
    java XML 通过BeanUtils的population为对象赋值 根据用户选择进行dom4j解析
    java基础 xml 使用dom4j解析 xml文件 servlet根据pattern 找到class
  • 原文地址:https://www.cnblogs.com/unlasting/p/12312362.html
Copyright © 2020-2023  润新知