Spring Boot

Spring Boot

瞻山识璞,临川知珠

官方文档

1. 概述

  1. 定义

SpringBoot是一个基于Spring4.0的javaweb快速开发框架,策略:开箱即用和约定优于配置,作者:Pivotal团队

  1. 与SSM区别
序号 SSM SpringBoot
1 Tomcat:war包 内嵌Tomcat :jar包
  1. 微服务

微服务是一种高内聚,低耦合架构风格,James Lewis,Martin Fowler

  1. SpringBoot 2.7.8要求
工具 Version
jdk Java 8
Spring Framework 5.3.25
Maven 3.5+
Gradle 6.8.x, 6.9.x, and 7.x
Tomcat 9.0 4.0
Jetty 9.4 3.1
Jetty 10.0 4.0
Undertow 2.0 4.0

2. 项目结构分析

2.1 创建方式

2.2 项目结构

1、程序的主启动类(程序的主入口)

2、一个 application.properties 配置文件(SpringBoot的核心配置文件)

3、一个 测试类

4、一个 pom.xml

  • pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<!--有一个父项目 控制版本与打包-->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<groupId>com.xxy</groupId>
	<artifactId>helloworld</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>helloworld</name>
	<description>first project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<!--所有的SpringBoot依赖都是spring-boot-starter开头-->
	<dependencies>
		<!--Web依赖:tomact.dispatcherServlet.xml-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!--单元测试-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
        <!--热部署开发工具-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
	</dependencies>

	<build>
		<!--jar包插件-->
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

2.3 修改配置

  1. 修改端口
server.port=8081
  1. 修改运行图标
                              __
                     /\    .-" /
                    /  ; .'  .'
                   :   :/  .'
                    \  ;-.'
       .--""""--..__/     `.
     .'           .'    `o  \
    /                    `   ;
   :                  \      :
 .-;        -.         `.__.-'
:  ;          \     ,   ;
'._:           ;   :   (
    \/  .__    ;    \   `-.
 没有bug ;     "-,/_..--"`-..__)
     '""--.._:

3. 原理初探

3.1 自动配置

  • pom.xml文件

    • spring-boot-starter-parent 核心依赖在父工程中spring-boot-dependencies,锁定了版本,不需要写版本
<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
  • 启动器【springBoot 启动场景】
    • spring-boot-starter,我们需要什么功能,找到对应的启动器就可以了,starter,比如spring-boot-starter-web就是自动导入web环境所有依赖
<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
  • 主程序
package com.xxy.helloworld;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//@SpringBootApplication 标注这是一个Spring Boot的应用,启动类
@SpringBootApplication
public class HelloworldApplication {
   

	public static void main(String[] args) {
   
		//将springBoot应用启动
		//run 开启了一个服务
		//SpringApplication 判断普通项目还是web项目,初始化器,监听器,找到Main的运行方法或者主类
		SpringApplication.run(HelloworldApplication.class, args);
	}

}
  • @SpringBootApplication下的注解

    1. springboot配置@SpringBootConfiguration

    2. spring自动配置 全面接管SpringMVC的配置@EnableAutoConfiguration

    3. springboot自动配置扫描:有判断条件,只有导入了先对应的start,自动装配才会生效@ComponentScan

    @org.springframework.boot.SpringBootConfiguration  //springboot的配置
      - @Configuration //spring 配置类
        -- @Component //说明者也是一个Spring的组件
    @org.springframework.boot.autoconfigure.EnableAutoConfiguration //自动配置ioc注入类
        - @AutoConfigurationPackage //自动配置包
        	--@Import({
         Registrar.class}) //自动配置 ‘包注册’
        - @Import({
         AutoConfigurationImportSelector.class})//自动配置导入选择器
        //获取所有(候选)的配置
         -- 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;
        }
    
  • 结论:

springboot所有自动配置都是启动时进行加载:spring.factories,里面有判断条件,条件不满足,就会无效,有了启动器,自动装配才会生效;

自动装配的原理

  • SpringBoot启动会加载大量的自动配置类
  • 寻找我们的功能是否在默认自动配置中
  • 查看自动配置类中配置了哪些组件 (没有就需要手动配置)
  • 添加组件时会从properties类中获取一部分属性
  • XX AutoConfigurartion:给容器添加组件
  • XX Properties:封装配置文件的属性,.yaml
  • 可以通过yml文件debug: true来查看自动配置的生效

3.2 SpringApplication类

  1. SpringApplication做了下面四件事
  • 推断应用的类型是普通的项目还是Web项目

  • 查找并加载所有可用初始化器 , 设置到initializers属性中

  • 找出所有的应用程序监听器,设置到listeners属性中

  • 推断并设置main方法的定义类,找到运行的主类

public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
   
    // ......
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    this.setInitializers(this.getSpringFactoriesInstances();
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = this.deduceMainApplicationClass();
}
  1. run():
    ①配置环境参数
    ②推断并设置main方法的定义类,找到运行的主类
    ③run方法里面有一些监听器,这些监听器是全局存在的,它的作用是获取上下文处理一些bean,所有的bean无论是加载还是生产初始化多存在。

3.3 自动配置加深

  1. 自动配置原理

Spring Boot通过@EnableAutoConfiguration注解开启自动配置,对jar包下的spring.factories文件进行扫描,这个文件中包含了可以进行自动配置的类,当满足@Condition注解指定的条件时,便在依赖的支持下进行实例化,注册到Spring容器中。
通俗的来讲,springboot的自动配置就是用注解来对一些常规的配置做默认配置,简化xml配置内容,使你的项目能够快速运行。

  1. @Conditional派生注解
序号 注解名称 作用
1 @Conditional 作用(判断是否满足当前指定条件)
2 @ConditionalOnJava 系统的java版本是否符合要求
3 @ConditionalOnBean 容器中存在指定Bean
4 @ConditionalOnMissingBean 容器中不存在指定Bean
5 @ConditionalOnExpression 满足SpEL表达式指定
6 @ConditionalOnClass 系统中有指定的类
7 @ConditionalOnMissingClass 系统中没有指定的类
8 @ConditionalOnSingleCandidate 容器中只有一个指定的Bean,或者这个Bean是首选Bean
9 @ConditionalOnProperty 系统中指定的属性是否有指定的值
10 @ConditionalOnResource 类路径下是否存在指定资源文件
11 @ConditionalOnWebApplication 当前是web环境
12 @ConditionalOnNotWebApplication 当前不是web环境
13 @ConditionalOnJndi JNDI存在指定项

4. 注入配置文件

结论:用yaml更好,除了SPEL表达式;如果yml和properties同时都配置了端口,默认会使用properties配置文件的!

4.1 导入文件处理器

<!--	防止@ConfigurationProperties(prefix = "person")注入报红-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>

4.2 编写配置文件

  • application.properties文件
# Spring Boot配置文件,修改SpringBoot自动配置的默认值
# 格式 key=value
  • application.yaml文件
# Spring Boot yaml配置
# 规范: key:空格value
# yaml一般是utf-8格式,可以注入配置文件

# 设置服务器端口号
server:
  port: 8081

# person对象赋值
person:
  name: lisi${
   random.uuid}
  age: ${
   random.int}
  isHappy: false
  birth: 2000/10/22
  maps: {
   k1: v1,k2: v2}
  # hello: jj
  lists:
    - code
    - music
    - girl
  dog:
    name: ${
   person.hello:hello}_旺财
    age: 3

# 数组
pets: [cat,dog,pig]
# 行内规范对象
student: {
   name: hh, age: dd}

4.3 进行绑定注入

@Component
@ConfigurationProperties(prefix = "person")
public class Person {
   
    private String name;
    private int age;
    private boolean isHappy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
   //get、set、toString方法
}

@Component
//加载指定的配置文件
@PropertySource(value = "classpath:dog.properties")
public class Dog {
   
    //通过SPEL表达式取出配置文件的值
    @Value("${name}")
    private String name;
    @Value("5")
    private int age;
  //get\set\toString方法
}

4.4 松散绑定

yaml可以是-和_和驼峰式命名相互绑定,根据set方法赋值

4.5 JSR303校验

@Validated//Spring数据验证 @Valid:JDK提供的(标准JSR-303规范),不知道用哪个可以直接找源码javax.validation.constraints

	<!--jsr303验证-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-validation</artifactId>
		</dependency>
约束注解名称 约束注解说明
@Null 用于验证对象为null
@NotNull 用于对象不能为null,无法查检长度为0的字符串
@NotBlank 只用于String类型上,不能为null且trim()之后的size>0
@NotEmpty 用于集合类、String类不能为null,且size>0。但是带有空格的字符串校验不出来
@Size 用于对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length 用于String对象的大小必须在指定的范围内
@Pattern 用于String对象是否符合正则表达式的规则
@Email 用于String对象是否符合邮箱格式
@Min 用于Number和String对象是否大等于指定的值
@Max 用于Number和String对象是否小等于指定的值
@AssertTrue 用于Boolean对象是否为true
@AssertFalse 用于Boolean对象是否为false
@Past 验证 Date 和 Calendar 对象是否在当前时间之前
@Future 验证 Date 和 Calendar 对象是否在当前时间之后

4.6 配置文件yaml优先级(从高到低);互补配置;可以通过spring.config.location改变默认位置

– file:./config/

– file:./

–classpath:/config/

–classpath:/

4.7 配置文件服务端口配置(建议)

# 设置服务器端口号
server:
  port: 8081
  spring:
profiles: 
active: dev
---
server:
  port: 8082
spring:
profiles: dev
active: dev
---
server:
  port: 8083
  spring:
  profiles: test
---

5. SpringBoot Web开发

5.1 静态资源

  • WebMvcAutoConfiguration类源码
//源码
public void addResourceHandlers(ResourceHandlerRegistry registry) {
   
            if (!this.resourceProperties.isAddMappings()) {
    //判断是否自定义
                logger.debug("Default resource handling disabled");
            } else {
   
                Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
                CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
                if (!registry.hasMappingForPattern("/webjars/**")) {
   
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{
   "/webjars/**"}).addResourceLocations(new String[]{
   "classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }//第一个静态资源的位置

                String staticPathPattern = this.mvcProperties.getStaticPathPattern();//获取静态资源的路径
                if (!registry.hasMappingForPattern(staticPathPattern)) {
   
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{
   staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }

            }
        }
   <!--引入jquery包-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.6.0</version>
        </dependency>

静态资源放的位置:(优先级从高到低),自己定义路径

# 自定义静态资源位置
spring.mvc.static-path-pattern=/hello/,classpath:/xxy/
  1. 导入依赖包,classpath:/META-INF/resources/webjars/
  2. classpath:/resources/
  3. classpath:/static/(默认)
  4. classpath:/public/
  5. /**

5.2 首页

  • 源码
@Bean
        public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
   
            WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
            welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
            welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
            return welcomePageHandlerMapping;
        }

        private Optional<Resource> getWelcomePage() {
   
            String[] locations = WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations());
            return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
        }

        private Resource getIndexHtml(String location) {
   
            return this.resourceLoader.getResource(location + "index.html");
        }
package com.xxy.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

//在templates目录下的所有页面,只能通过Controller来跳转
//需要模板引擎的支持 thymeleaf依赖
@Controller
public class IndexController {
   
    @RequestMapping("/index")
    public String index() {
   
        return "index";
    }
}

5.3 模板引擎(比较少用,大多数前后端分离,用来渲染,vue使用pug)

Thymeleaf官网

   <!--导入Thymeleaf模板引擎-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

5.4 装配扩展SpringMVC

  • 自定义视图解析器
package com.xxy.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值