前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot基础(二、原理分析)

SpringBoot基础(二、原理分析)

作者头像
营琪
发布2019-11-04 16:54:16
4130
发布2019-11-04 16:54:16
举报
文章被收录于专栏:营琪的小记录营琪的小记录


接着上一篇SpringBoot基础(一、快速入门)的介绍,我们来简单的谈谈SpringBoot的原理分析。

谈到原理,那么就从它的核心入手,“约定大于配置”,这句话可以分为以下两点。

  • 起步依赖,定义了对其他库的传递依赖,也就是某项功能对应的坐标打包在一起
  • 自动配置,SpringBoot在运行时,会自动配置。

根据第一篇文章的项目,我们好像没什么也选项呀!我们就配置了坐标和引导类。

先从坐标入手吧!

起步依赖原理分析

先CTRL+左键,进入 spring-boot-starter-parent 这个父工程看看。

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>                                            //引入父工程
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.1.5.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
  </parent>
  <artifactId>spring-boot-starter-parent</artifactId>
  <packaging>pom</packaging>
  <name>Spring Boot Starter Parent</name>
  <description>Parent pom providing dependency and plugin management for applications
		built with Maven</description>
  <url>https://projects.spring.io/spring-boot/#/spring-boot-starter-parent</url>
  <properties>                                       //属性配置
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <resource.delimiter>@</resource.delimiter>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.target>${java.version}</maven.compiler.target>
  </properties>
  <build>
    <resources>
      <resource>
        <filtering>true</filtering>
        <directory>${basedir}/src/main/resources</directory>
        <includes>                                //导入非默认配置资源
          <include>**/application*.yml</include>  //.yml文件类型  server: {port: 8888,xxx: xxx},{...}
          <include>**/application*.yaml</include>
          <include>**/application*.properties</include>
        </includes>
      </resource>
    <pluginManagement>                            //插件管理
    ....
    </pluginManagement>
  </build>
</project>

这个工程有一些属性配置,导入非默认配置,插件管理

好像 spring-boot-starter-parent , 还存在父工程 spring-boot-dependencies。同理,进去看看

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"             
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.1.5.RELEASE</version>
  <packaging>pom</packaging>
  <name>Spring Boot Dependencies</name>
  <description>Spring Boot Dependencies</description>
  <url>https://projects.spring.io/spring-boot/#</url>
  <licenses>
   ....
  </licenses>
  <developers>
   ....
  </developers>
  <scm>
    <url>https://github.com/spring-projects/spring-boot</url>
  </scm>
  <properties>
       <spring.version>5.1.7.RELEASE</spring.version>    //版本锁定
       <junit.version>4.12</junit.version>
        ....
  </properties>
  <dependencyManagement>
      <dependencies>
         <dependency>                                    //导入坐标
         <groupId>org.springframework</groupId>
         <artifactId>spring-core</artifactId>
         <version>${spring.version}</version>
         </dependency>
      </dependencies>
        ....
  </dependencyManagement>
  <build>
      <pluginManagement>
           ....                                           //导入插件
      </pluginManagement>
  </build>
</project>

嗯,很多从开始的版本锁定,依赖管理,插件管理。也就是启动Spring所需要的配置都有默认的了??

那么我么加的WEB功能呢? 也有类似的坐标??

那么进去看看 spring-boot-starter-web。

我们可以猜猜看,这个坐标下有什么东西 springMVC的坐标? Spring-web坐标??json工具的坐标??

点击进去,发现,答对了,这个都存在,还有其他的tomcat服务器坐标等。。。

但是,发现还引用spring-boot-starters这个父工程,相比第一个差了一个parent。里面有的咱就不说了,跟第一个类似,有兴趣可以试试。

现在从引导类入手,看看有啥,没啥, 就一个注解好像特殊点。那就看看注解

自动配置原理分析

按住CTRL+左键进入 @SpringBootApplication 注解

代码语言:javascript
复制
package org.springframework.boot.autoconfigure;

import ...

@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 {};
    
    ......
}

发现三个有点眼熟的注解,并分别点进去看看

@SpringBootConfiguration,里面有一个@Configuration注解,这不就是基于Java的配置吗?标志着该类是一个配置类。

@ComponentScan,相当开启全局注解扫描。

@EnableAutoConfiguration,SpringBoot自动配置功能开启

代码语言:javascript
复制
@EnableAutoConfiguration  -->  @Import({AutoConfigurationImportSelector.class}) -->AutoConfigurationImportSelector.class

public class AutoConfigurationImportSelector {
        protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }
....
}

我们根据提示,知道AutoConfigurationImportSelector此类,会加载META-INF/目录下的文件。那找找这个类看看呗。

也就是此类中存有SpringBoot自动配置的信息。

修改配置信息

一、我们可以得到默认配置信息名称和值,以及配置方式。

二、spring-boot-starter-parent中提到加载非默认配置信息,进而让可以改变SpringBoot的配置信息。

那我们修改8080端口看看吧,改为8888。

寻找到端口的配置信息

  • 方法一:到底SpringBoot中是怎么配的。进入spring.factories搜索到自动配置servlet的类吧
代码语言:javascript
复制
ServletWebServerFactoryAutoConfiguration --> @EnableConfigurationProperties({ServerProperties.class}) --> ServerProperties

@ConfigurationProperties(                //配置信息映射注解,作用同@Value("${server.port},{server.xxx}")
    prefix = "server",
    ignoreUnknownFields = true
)
public class ServerProperties {          
    private Integer port;                
    ....
}
  • 方法二:进入spring-configuration-metadata.json中搜索port
代码语言:javascript
复制
    {
      "name": "server.port",
      "type": "java.lang.Integer",
      "description": "Server HTTP port.",
      "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties",
      "defaultValue": 8080
    },

既然知道了是怎么样是属性了,那我们配8888端口看看呗!

创建application.properties文件,并写上server.port=8888

访问看看

总结

SpringBoot简单的原理分析,到此就结束了。约定大于配置,一系列的默认自动配置,降低人为因数导致的错误,简化开发。

也就两点,起步依赖 、自动配置 。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 起步依赖原理分析
  • 自动配置原理分析
  • 修改配置信息
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档