飞道的博客

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

1295人阅读  评论(0)

 哈喽~大家好,这篇看看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<String> 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的注入

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


转载:https://blog.csdn.net/aasd23/article/details/127583044
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场