• springboot 项目起步讲解及自动装配原理


     哈喽~大家好,这篇看看springboot 项目起步讲解及自动装配原理。

     🥇个人主页个人主页​​​​​             

    🥈 系列专栏:【Java框架】   

    🥉与这篇相关的文章:            

     号外号外,我最近发现了一个非常棒的人工智能学习网站,它的内容通俗易懂,风趣幽默,让人印象深刻。我想和大家分享这个网站,点击链接即可访问。

    目录

    一、前言

    1、SpringBoot 简介

    二、SpringBoot 入门案例

    1、准备

    2、测试一下

    3、效果展示

    三、SpringBoot 自动装配原理

    1、SpringBoot 自动装配原理(自个认为)

    2、举个例子

    3、getRunListeners

    4、spring.factories

    5、@SpringBootConfiguration

    6、@ComponentScan

    7、@EnableAutoConfiguration

    五、总结


    一、前言

    1、SpringBoot 简介

    SpringBoot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化 Spring 应用的初始搭建以及开发过程。

    我们在学习 Spring 的时候说过 Spring 框架是为了简化开发的,而 SpringBoot 是为了简化 Spring 开发的,由此可见,使用 SpringBoot 开发将会更加的方便简捷。

    二、SpringBoot 入门案例

    1、准备

    新建项目选择 Spring Initializr,网址填写 https://start.aliyun.com/(阿里云的网站)

    选择要使用的开发工具,常用的有(Spring Web、Lombok、Mysql Driver、Oracle Driver 等)

    注:

    1、在创建好的工程中不需要创建配置类

    2、创建好的项目会自动生成其他的一些文件,而这些文件目前对我们来说没有任何作用,所以可以将这些文件删除。

    可以删除的目录和文件如下:.mvn、.gitignore、HELP.md、mvnw、mvnw.cmd

    2、测试一下

    新建实体类 User

    1. @Data
    2. @NoArgsConstructor
    3. @AllArgsConstructor
    4. @ToString
    5. public class User {
    6.    private String username;
    7.    private String password;
    8. }

    新建控制层类

    1. @Controller
    2. @RequestMapping("/user")
    3. public class HelloAction {
    4.    @RequestMapping("/userDetail")
    5.    @ResponseBody
    6.    public User userDetail() {
    7.        User user = new User("123", "456");
    8.        return user;
    9.   }
    10. }

    application.yml 文件配置

    1. server:
    2.  port: 8081
    3.  servlet:
    4.    context-path: /

    一个配置端口号,另一个配置应用的上下文路径。

    找到我们的启动类,点击启动

    访问路径

    http://localhost:8081/user/userDetail

    3、效果展示

    三、SpringBoot 自动装配原理

    1、SpringBoot 自动装配原理(自个认为)

    我们创建的一个新工程,默认的 SpringApplication.run 传入启动类的class以及main方法的参数。

    eg:

    1. @SpringBootApplication
    2. public class Text {
    3.    public static void main(String[] args) {
    4.        SpringApplication.run(Text.class,args);
    5.   }
    6. }

    按住ctrl 点击 run

    首先我们从SpringApplication的run方法开始分析,在该方法中调用重载的run方法。

    在重载的run方法中,创建了一个SpringApplication实例,并调用重载run方法。

    点击 SpringApplication 进去

    在SpringApplication构造函数中调用了重载的构造函数。

    在重载的构造函数中,完成了当前环境的推断以及ApplicationContextInitializer实现类实例化以及ApplicationListener实现类的实例化等。

    2、举个例子

    我们建了一个web的项目,也许大家比较好奇SpringBoot是如何推断当前运行环境,这里我们就先分析这个推断运行环境逻辑。

    在SpringApplication的重载的构造函数中点击 deduceFromClasspath

    跳转到 deduceFromClasspath

    这里判断 是什么类型默认为 SERVLET。

    当然 SpringApplication 不止做了这些初始化。

    明白SpringBoot是如何推断当前运行环境后,接下来我们就分析SpringBoot的核心方法 run方法。

    3、getRunListeners

    getRunListeners 首先来分析getRunListeners方法,在该方法中,通过getSpringFactoriesInstances方法来获取classpath下META-INF/spring.factories文件中key为org.springframework.boot.SpringApplicationRunListener的value,然后并进行实例化,将结果作为参数传入到SpringApplicationRunListeners的构造函数中,最后返回该实例。

    1. private SpringApplicationRunListeners getRunListeners(String[] args) {
    2. Class[] types = new Class[] { SpringApplication.class, String[].class };
    3. return new SpringApplicationRunListeners(logger,
    4. getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
    5. }

    ​ 

    4、spring.factories

    spring.factories用键值对的方式记录了所有需要加入容器的类,EnableAutoConfigurationImportSelector的selectImports方法返回的类名,来自spring.factories文件内的配置信息,这些配置信息的key等于EnableAutoConfiguration,因为spring boot应用启动时使用了EnableAutoConfiguration注解,所以EnableAutoConfiguration注解通过import注解将EnableAutoConfigurationImportSelector类实例化,并且将其selectImports方法返回的类名实例化后注册到spring容器。

    即spring.factories文件是帮助spring-boot项目包以外的bean(即在pom文件中添加依赖中的bean)注册到spring-boot项目的spring容器中。由于@ComponentScan注解只能扫描spring-boot项目包内的bean并注册到spring容器中,因此需要@EnableAutoConfiguration注解来注册项目包外的bean。而spring.factories文件,则是用来记录项目包外需要注册的bean类名。

    我们在来看看 @SpringBootApplication 注解

    点击 @SpringBootApplication ,发现他其实是个复合注解

    1. @Target({ElementType.TYPE})
    2. @Retention(RetentionPolicy.RUNTIME)
    3. @Documented

    这三个不用管,这是大部分的复合注解都有的,主要看这三个。

    1. @SpringBootConfiguration
    2. @EnableAutoConfiguration
    3. @ComponentScan

    5、@SpringBootConfiguration

    先来看第一个:@SpringBootConfiguration

    进入这个注解之后会发现

    就是一个@Configuration啊,一个JavaConfig配置类

    @Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

    1. @Configuration // 标记为配置类
    2. public class MyConfig {
    3. @Bean // 给容器添加组件,以方法名作为组件的id,返回类型就是组件的类型,返回值就是组件在容器中的实例
    4. public Book defaultBook() {
    5. return new Book("白夜行", "东野圭吾", "人民邮电出版社");
    6. }
    7. @Bean // 给容器添加组件,以方法名作为组件的id,返回类型就是组件的类型,返回值就是组件在容器中的实例
    8. public Periodical defaultPeriodical() {
    9. return new Periodical("时代经贸", "赵建锁", "北京财贸职业学院");
    10. }
    11. }

    test 类

    1. @SpringBootTest
    2. class ConfigurationApplicationTests {
    3. @Autowired
    4. MyConfig myConfig;
    5. @Test
    6. void contextLoads() {
    7. System.out.println(myConfig.defaultBook());
    8. System.out.println(myConfig.defaultPeriodical());
    9. }
    10. }

     

    6、@ComponentScan

    这个注解相信大家都认识了,组件扫描

    这个扫描的范围是:SpringBoot主启动类的同级路径及子路径

    7、@EnableAutoConfiguration

    @EnableAutoConfiguration 点击进去,核心:@Import(AutoConfigurationImportSelector.class)

    看看AutoConfigurationImportSelector,它是实现了 DeferredImportSelector 的一个类,使用了 selectImports 这个方法,返回值类型是String[],返回的是要加载的Config配置文件的全包名,通过返回这个全包名,我们就能自动装配上这些配置文件下定义的bean对象,从而达到了自动装配的目的!

    继续反推,看到 AutoConfigurationEntry 这个类,发现autoConfigurationEntry中保存着我们需要的配置信息,它是通过getAutoConfigurationEntry方法获取的,于是我们继续深入,进入getAutoConfigurationEntry方法

    发现返回了两个参数 configurations, exclusions。

    configurations显然使我们需要的配置文件,也是我们最关心的,而exclusions字面意思是排除,也就是不需要的,那我们接下来应该关注configurations到底是怎么来的。

    方法参数里面有个 Annotation(注解) 加上configurations,确定一行代码

    List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

    点击getCandidateConfigurations,查看

    有一串英文 “No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.”,意思是“在META-INF/spring.factories中找不到自动配置类。如果您使用的是自定义打包,请确保文件正确。”

    在前面看到配置文件就叫spring.factories,存放的路径是META-INF/spring.factories,很明显就是这个路径下的文件

    这里的EnableAutoConfiguration注解,正是我们此行的起点啊…

    到这里,自动装配到底是什么,应该比较清楚了,原来他是帮我们加载了各种已经写好的Config类文件,实现了这些JavaConfig配置文件的重复利用和组件化

    自动装配笔记参考于这篇博客

    五、总结

    自动配置简单来说呢,就是将第三方的组件自动装载到IOC容器里面,不需要开发人员再去编写相关的配置,在SpringBoot应用里面呢只需要加上@SpringBootApplication注解就可以实现自动配置,SpringBootApplication它是一个复合注解,真正实现自动装配的注解是@EnableAutoConfiguration注解。自动装配的实现呢主要依靠三个核心的关键技术:

    1、引入Starter,启动依赖组件的时候,这个组件里面必须包括@Configuration配置类,然后我需要通过Bean注解去声明需要装配到IOC容器里面的Bean对象

    2、这个配置类是放在第三方的jar包里面,然后通过Spring Boot中约定大于配置的理念,去把配置类的全路径放在件META_INF/Spring.factories文件里面,SpringBoot就可以知道第三方jar包里面配置类的位置,它主要是依靠Spring里面的SpringFactorierLoader来完成的

    3、SpringBoot拿到所有第三方jar包声明的配置类之后,再通过ImportSelector这样一个接口来实现对这些配置类的动态加载,从而去完成自动装配这样的一个动作。

    4、个人理解

    SpringBoot是约定优于配置这一理念下的一个产物,所以在很多的地方都会看到这一类的思想,它的出现让开发人员可以更加聚焦在业务代码的编写上,而不需要去关系和业务无关的配置,其实自动装配的思想在springframework3.x版本里面的@enable注解,就已经有了实现的一个雏形,@enable注解时候一个模块驱动的意思,就是说我们只要增加@enable注解,就可以自动打开某个功能,而不需要针对这个功能去做Bean的配置,@enable注解的底层是帮我们自动完成这样的一个模块相关bean的注入

    不积跬步无以至千里,趁年轻,使劲拼,给未来的自己一个交代!向着明天更好的自己前进吧!

  • 相关阅读:
    26.CF1000F One Occurrence
    Dart HttpClient 网络请示框架的使用详解
    PLC中实现一键启停的9种方法程序示例汇总
    图像格式导致halcon读取失败
    numpy.where
    共读《redis设计与实现》-单机(一)
    详解AQS中的condition源码原理
    正则表达式
    提升学校教育质量,还有这种操作?!
    【C++】string 之 substr、insert、erase函数的学习
  • 原文地址:https://blog.csdn.net/aasd23/article/details/127583044