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

举报
追zhui 发表于 2024/10/26 15:05:23 2024/10/26
【摘要】 ​ ​编辑 哈喽~大家好,这篇看看springboot 项目起步讲解及自动装配原理。 🥇个人主页:个人主页​​​​​             🥈 系列专栏:【Java框架】   🥉与这篇相关的文章:             【JAVAEE框架】MyBatis与Spring的整合(上)【JAVAEE框架】MyBatis与Spring的整合(上)_程序猿追的博客-CSDN博客【JAVAEE...

 编辑


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


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

🥈 系列专栏:【Java框架】   

🥉与这篇相关的文章:            



 【JAVAEE框架】MyBatis与Spring的整合(上) 【JAVAEE框架】MyBatis与Spring的整合(上)_程序猿追的博客-CSDN博客
【JAVAEE框架】浅谈 AOP 及代码实现 【JAVAEE框架】浅谈 AOP 及代码实现_程序猿追的博客-CSDN博客
【JAVAEE框架】浅谈 Spring 框架的两大核心思想 AOP 与 IOP 【JAVAEE框架】浅谈 Spring 框架的两大核心思想 AOP 与 IOP_程序猿追的博客-CSDN博客

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

目录

一、前言

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

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
​
    private String username;
    private String password;
​
}

新建控制层类

@Controller
@RequestMapping("/user")
public class HelloAction {
​
    @RequestMapping("/userDetail")
    @ResponseBody
    public User userDetail() {
        User user = new User("123", "456");
​
        return user;
    }
​
}

application.yml 文件配置

server:
  port: 8081
  servlet:
    context-path: /

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

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

编辑



访问路径

http://localhost:8081/user/userDetail

3、效果展示

编辑


三、SpringBoot 自动装配原理

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

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

eg:

@SpringBootApplication
public class Text {
​
    public static void main(String[] args) {
        SpringApplication.run(Text.class,args);
    }
​
}

按住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的构造函数中,最后返回该实例。

private SpringApplicationRunListeners getRunListeners(String[] args) {
    Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
    return new SpringApplicationRunListeners(logger,
            getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
​

编辑​ 

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 ,发现他其实是个复合注解

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

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

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

5、@SpringBootConfiguration

先来看第一个:@SpringBootConfiguration

进入这个注解之后会发现

编辑



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

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

@Configuration  // 标记为配置类
public class MyConfig {

    @Bean // 给容器添加组件,以方法名作为组件的id,返回类型就是组件的类型,返回值就是组件在容器中的实例
    public Book defaultBook() {
        return new Book("白夜行", "东野圭吾", "人民邮电出版社");
    }

    @Bean // 给容器添加组件,以方法名作为组件的id,返回类型就是组件的类型,返回值就是组件在容器中的实例
    public Periodical defaultPeriodical() {
        return new Periodical("时代经贸", "赵建锁", "北京财贸职业学院");
    }

}

test 类

@SpringBootTest
class ConfigurationApplicationTests {

    @Autowired
    MyConfig myConfig;

    @Test
    void contextLoads() {
        System.out.println(myConfig.defaultBook());
        System.out.println(myConfig.defaultPeriodical());
    }

}

编辑

 编辑



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的注入



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

编辑



【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。