SpringBoot深度解析及使用教程(不吹不黑,一篇从入门到放弃)

目录

 

 

入门部分

1.Spring Boot 简介

2.微服务

3.环境准备

4.Maven配置

5.IDEA配置

6.修改Banner

7.使用IDEA创建一个项目

8.添加Banner文件

9.创建Controller类

10.一个方法映射多个URL地址

11.窄化请求

12.其他创建方式

13.其他运行方式

讲原理部分

1、从POM文件讲原理

2、启动器

3、主程序类,主入口类

4、自动配置原理

参数传递

1.get方式Url传参:

2.get方式Url传参:

3.get方式Url传参:

4.POST方式传递数据

5.POST传递字符串文本

6.@requestbody接收参数

SwaggerAPI框架

1.添加依赖

2.Swagger配置

3.使用注解

4.Webjars的使用

springboot-配置文件的使用

1、配置文件的使用

2、切换配置文件

1、多配置文件

2、单配置文件(分块)

3、激活指定profile

4、配置文件加载位置

springboot-配置文件详解

1.YML是什么

2.YML语法

字面量

对象、Map

数组

springboot-配置文件的注入

1、单值注入

2、批量注入

3、两种注入的区别

4、注入值的数据校验

springboot-其他配置文件

1、@PropertySource

2、@ImportResource

3、@Bean

4、配置文件占位符


 

入门部分

1.Spring Boot 简介

简化Spring应用开发的一个框架;

整个Spring技术栈的一个大整合;

J2EE开发的一站式解决方案;

spring官网

2.微服务

2014,martin fowler

微服务:架构风格(服务微化)

一个应用应该是一组小型服务;可以通过HTTP的方式进行互通;

单体应用:ALL IN ONE

微服务:每一个功能元素最终都是一个可独立替换和独立升级的软件单元;

 

3.环境准备

SpringBoot2.0环境约束

  • jdk1.8+;java version “1.8.0_112”
  • maven 3.3+;Apache Maven 3.5.4
  • A favorite text editor or IDE:IntelliJ IDEA 2018.2.6
  • SpringBoot 2.1.1.RELEASE

4.Maven配置

$M2_HOME\conf\settings.xml 配置文件t添加如下内容

  • 在之间添加如下内容
  • 作用:国内maven仓库镜像(众所周知的原因国内不能很好的访问maven中央仓库)
<mirror>
    <id>alimaven</id>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>        
</mirror>
  • 在 之间添加如下内容
  • 作用:指定项目编译运行使用的JDK版本
<profile>
    <id>jdk-1.8</id>
    <activation>
        <jdk>1.8</jdk>
        <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
    </properties>
    <!-- 如果是在学校或公司有maven私服,可以在这里配置私服 -->
    <repositories>
        <repository>
            <id>accp</id>
            <name>accp</name>
            <url>http://192.168.1.48:8081/repository/accp/</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>
    <!-- 如果没有私服,这里不用配置 -->
</profile>

5.IDEA配置

整合Maven进来

6.修改Banner

1
2
3
4
5
6
7
8
9
10
${AnsiColor.BLUE}
 _______  _______  ______  
|       ||       ||      | 
|____   ||    ___||  _    |
 ____|  ||   |___ | | |   |
| ______||    ___|| |_|   |
| |_____ |   |___ |       |
|_______||_______||______| 

-----版本号-----${spring-boot.version}

文字Banner可以从这个网站生成(有很多种字体样式可以选择)

http://patorjk.com/software/taag

${AnsiColor.BLUE} 表示Banner文字的颜色

${spring-boot.version} 当前使用的SpringBoot版本

7.使用IDEA创建一个项目

  • 目录结构说明
    • src/main/java: Java代码的目录
    • src/main/resources: 资源目录
    • src/test/java: 测试代码的目录
    • src/test/resources: 测试资源目录
  • POM文件说明

8.添加Banner文件

在resources目录下创建banner.txt文件,添加以下内容

可以更换成你自己的banner

${AnsiColor.BLUE}
 _______  _______  ______
|       ||       ||      |
|____   ||    ___||  _    |
 ____|  ||   |___ | | |   |
| ______||    ___|| |_|   |
| |_____ |   |___ |       |
|_______||_______||______|

-----版本号-----${spring-boot.version}

9.创建Controller类

  • 文件模板修改

 

package com.example.demo.controller;

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

@Controller
public class HelloWorld {
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    @ResponseBody  //不加这行注解返回的是字符串其实是一个逻辑的说明,拼接了前缀后缀去找真正的视图,要想返回文本就需要加上这个注解
    public String hello() {
        return "hello SpringBoot";
    }
}

直接右上角运行

访问http://localhost:8080/hello

  • 注解的方式还有一种,和上面的效果一样

如果这个类下面的所有方法都是加了@ResponseBody注解,我们可以把@Controller@ResponseBody去掉,仅使用@RestController注解

package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorld {
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "hello SpringBoot";
    }
}
  • 还可以简化

如果我们使用的是@RequestMapping的GET请求可以简化使用@GetMapping注解

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorld {
    @GetMapping("/hello")
    public String hello() {
        return "hello SpringBoot";
    }
}

注解说明:

@RestController: 处理http请求:等同于@Controller+@ResponseBody
@RequestMapping: value = "访问的路由" method = 请求方法
@GetMapping:以GET方式请求 相当于对@RequestMapping配置的缩写

10.一个方法映射多个URL地址

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorld {
    @GetMapping({"/hello", "/hi"}) //注意这里的{}
    public String hello() {
        return "hello SpringBoot";
    }
}

http://localhost:8080/hello

http://localhost:8080/hi

11.窄化请求

  • 类和方法都有value时,访问的地址是类上的地址拼接上方法上的地址。

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")//这个地址就叫做窄化请求
public class HelloWorld {
    @GetMapping("/hello")
    public String hello() {
        return "hello SpringBoot";
    }
}

http://localhost:8080/user/hello

12.其他创建方式

  • SPRING INITIALIZR:通过IDEA或者STS工具创建INITIALIZR项目(上面所写的项目创建就是这样)
  • 创建Maven项目手动添加依赖
  • 通过https://start.spring.io/ 生成定制项目

下面我们演示,创建Maven项目手动添加依赖

手动添加依赖

启动类需要自己手动编写,类名叫什么无所谓,但是必须添加一个注解叫@SpringBootApplication,然后在写一个main方法,

然后再编写一下他的控制器类,跟之前我们写的一样

启动,启动完成后会扫描的类 

下面我们演示,通过https://start.spring.io/ 生成定制项目

最后会下载一个ZIP包,我们可以解压到桌面然后通过IDEA导入这个项目

选择刚才解压的文件夹,一直下一步就行了

然后跟之前一样分开写类也可以跟下面一样写一起。

13.其他运行方式

  • 在IDE中直接运行
  • 发布Jar包运行

在pom/xml文件引用插件

<!-- 这个插件,可以将应用打包成一个可执行的jar包;-->
   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
       </plugins>
   </build>

导入这个maven插件,利用idea打包,

生成的jar包,可以使用java -jar xxx.jar启动

Spring Boot 使用嵌入式的Tomcat无需再配置Tomcat


讲原理部分

1、从POM文件讲原理

父项目

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

spring-boot-starter-parent他的父项目是:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.1.1.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
</parent>

这是真正管理Spring Boot应用里面所依赖的版本

Spring Boot的版本仲裁中心;

以后我们导入依赖默认是不需要写版本;

(没有在dependencies里面管理的依赖自然需要声明版本号)

太多了就放两张图感受一下就行啦。

2、启动器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

我们去他的官网看一下

spring-boot-starter-web

spring-boot-starter:spring-boot场景启动器,帮我们导入了web模块正常运行所依赖的组件;

点击进去可以看到帮我们引入很多web相关的依赖

Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter相关场景的所有依赖都会导入进来,要用什么功能就导入什么场景的启动器

3、主程序类,主入口类

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

@SpringBootApplication : Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

点进去这个注解可以看到下面的源码

@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 {
  • @SpringBootConfiguration : Spring Boot的配置类,标注在某个类上,表示这是一个Spring Boot的配置类
  • @Configuration : 配置类上来标注这个注解,配置类也是容器中的一个组件@Component
  • @EnableAutoConfiguration:开启自动配置功能

点击@SpringBootConfiguration可以看到下面的源码,这是SpringBoot的底层的注解叫@Configuration,之前我们在使用Spring的时候会出现大量的XML文件,后来在使用SpringBoot之后推荐我们使用类+注解的形式来使用配置,就再也不会出现大量的XML文件了,所以某些类要是做配置类必须加上@Configuration来标注他是配置类

点击@EnableAutoConfiguration可以看到下面的源码

  • 将主配置类(@SpringBootApplication标注的类 )的所在包及下面所有子包里面的所有组件都可以扫描到Spring容器;

下面我们做个试验

可以看到在启动类和控制器类在不同的包下面,那么我们在访问控制器类发现找不到了

所以我们一般会把启动类放在外层

  • 调用了SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader)
  • Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作;

  • 以前我们需要自己配置的东西,自动配置类都帮我们;
  • 有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;
  • J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-1.5.9.RELEASE.jar

4、自动配置原理

1)、SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration

2)、@EnableAutoConfiguration 作用:

  • 利用EnableAutoConfigurationImportSelector给容器中导入一些组件?

  • 可以查看selectImports()方法的内容;

  • List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置

SpringFactoriesLoader.loadFactoryNames()
扫描所有jar包类路径下  META-INF/spring.factories
把扫描到的这些文件的内容包装成properties对象
从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中

将类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中

精髓:

​ 1)、SpringBoot启动会加载大量的自动配置类

​ 2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;

​ 3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)

​ 4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;

xxxxAutoConfigurartion:自动配置类(给容器中添加组件);
xxxxProperties:封装配置文件中相关属性;

参数传递

参数传递可以说是服务端和外界沟通的主要方式
本段内容包括:

通过url传参
    |---get方式Url传参
        |---@PathVariable 即:url/id/1994 形式
        |---@RequestParam 即:url?username=zed形式
    |---POST方式传参
        |---@RequestParam
        |---请求体中加入文本
配置文件传参

1.get方式Url传参:

@PathVariable 路径传参,可以在路径上拼接参数的

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/hello/{name}")
    public String hello(@PathVariable("name") String name) {
        // 最后一个name是形参name,名字可以随意,但是前两个要保持一致
        return "hello " + name;
    }
}


2.get方式Url传参:

@RequestParam

如果请求参数的名字跟方法中的形参名字一致可以省略@RequestParam(“name”)

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(@RequestParam("name") String name) {
        System.out.println("获取到的name是:" + name);
        return "hello " + name;
    }
}

如果请求参数的名字跟方法中的形参名字一致可以省略@RequestParam(“name”),如下

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(String name) {
        System.out.println("获取到的name是:" + name);
        return "hello " + name;
    }
}


3.get方式Url传参:

@RequestParam+默认参数

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "admin") String n) {
        System.out.println("获取到的name是:" + n);
        return "hello " + n;
    }
}

注意:如果没有指定默认值,并且没有传递参数将会报错

Required String parameter 'name' is not present :name参数没有提供

  • 解决方案
    • 1.defaultValue = “xxx” :使用默认值
    • 2.required = false :标注参数是非必须的
package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", required = false) String n) {
        System.out.println("获取到的name是:" + n);
        return "hello " + n;
    }
}

4.POST方式传递数据

package com.example.demo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    Logger log = LoggerFactory.getLogger(HelloController.class);

    @PostMapping("/hello")
    public String add(@RequestParam("name") String name, @RequestParam("age") Integer age) {
        log.info(name + "  " + age);
        log.info(age.getClass().getSimpleName());   //打印age的类型,可以自动帮我们转的
        return "name:" + name + "\nage:" + age;
    }

}

因为POST请求不好通过浏览器模拟,所以我们使用Postman软件来实现

5.POST传递字符串文本

通过HttpServletRequest获取输入流

package com.example.demo.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@RestController
public class HelloController {

    @PostMapping("/postString")
    public String postString(HttpServletRequest request) {
        ServletInputStream is = null;
        StringBuilder sb = null;
        try {
            is = request.getInputStream();  //所有请求体中的内容会封装到request上。
            sb = new StringBuilder();
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = is.read(buf)) != -1) {
                sb.append(new String(buf, 0, len));
            }
            System.out.println(sb.toString());
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

}

6.@requestbody接收参数

  • @requestbody可以接收GET或POST请求中的参数
  • 把json作为参数传递,要用【RequestBody】
  • 附带着说一下使用postman方式设置content-type为application/json方式测试后台接口

下面是User的pojo类

package com.example.demo.pojo;

public class User {
    private String username;
    private String age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}
package com.example.demo.controller;

import com.example.demo.pojo.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    Logger log = LoggerFactory.getLogger(HelloController.class);

    @PostMapping("/user")
    public String user(@RequestBody User user) {
        log.info(user.toString());
        return null;
    }
}


SwaggerAPI框架

为了方便上面的API接口调试,我们可以使用:

  • Postman:模拟POST请求
  • Swagger:描述和测试API接口

1.添加依赖

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
</dependency>

2.Swagger配置

yml配置文件

swagger:
  title: SpringBoot学习
  description: SpringBoot快速入门
  version: 1.0.0
  name: jenrey
  url: https://jenrey.csdn.net
  email: jenrey@foxmail.com

 新建一个config包,下面新建一个SwaggerConfig.java文件,内容如下

package com.example.demo.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration  //配置类必须要加这个注解
@EnableWebMvc   //必须加上
@EnableSwagger2 //必须加上
@ConfigurationProperties(prefix = "swagger")    //把yml里面的基本信息导入到我们的配置类中,并制定前缀
@Data
//因为我们是API接口文档它必须要扫描控制器层,而控制器这些类在哪个包下面我们必须指定一下,通过一个组件扫描指定一下控制器所在的包
@ComponentScan(basePackages = {"com.example.demo.controller"})
public class SwaggerConfig {
    private String title;   //下面这些值我们直接在配置文件里面去写
    private String description;
    private String version;

    private String name;
    private String url;
    private String email;

    @Bean   //用注解的方式创建的Bean,生成的Bean是放到容器里面了,生成一个docker,docker要配置一个API的基本信息info
    public Docket customDocket() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
    }

    private ApiInfo apiInfo() {
        Contact contact = new Contact(name, url, email);    //然后基本信息里面有个联系人,需要联系人的姓名,url地址,邮箱
        return new ApiInfoBuilder() //返回一个ApiInfoBuilder
                .title(title)
                .description(description)
                .contact(contact)
                .version(version)
                .build();   //是用创建者方式调用build方法,帮我们返回一个ApiInfo给它放到容器里面
    }
}

新建一个WebMvcConfig.java文件,写入下面代码

package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
class WebMvcConfig implements WebMvcConfigurer {

    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

}

上面两个写好了之后就可以使用Swagger注解了,比如我们写一个控制类,来测试一下Swagger

3.使用注解

在控制器API上添加接口描述的注解

package com.example.demo.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Api(value = "用户模块的控制器")//注释这个类是干嘛的,我们使用Swagger下面的@Api注解
public class HelloSwagger {
    Logger log = LoggerFactory.getLogger(HelloSwagger.class);
    @GetMapping("/hello")
    @ApiOperation(value = "测试Swagger") //描述接口作用的
    /*
    @ApiImplicitParams(
            {@ApiImplicitParam(),@ApiImplicitParam()}
    )    //有多参数用这个
    */
    public String hello() {
        return "hello SpringBoot-Swagger";
    }
}

然后我们运行一下SpringBoot

输入上述的地址可以看到是Swagger的描述信息

http://localhost:8080/v2/api-docs

http://localhost:8080/swagger-ui.html

Swagger的具体用法,请参照 B站Swagger视频

4.Webjars的使用

其实就是把我们常用的一些,像jquery,BootStrap等组件都有Webjars的引入方式

官网:https://www.webjars.org/

把下面的配置写的pom中其实就是在我们的项目中添加了jquery 

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1-1</version>
</dependency>

通过jar包的方式引入了jQuery

再浏览器中可以通过如下地址访问到

http://localhost:8080/webjars/jquery/3.3.1-1/jquery.js

地址说明:/webjars/jquery/3.3.1-1/jquery.js

对应上面的 webjars/ artifactId/version/文件名

可以到项目中的jar包中具体查看。

所以我们通过这样的一个路径就可以请求到JQ了,是一种通过jar包来引入的方式,并不是向之前一样从官网或者其他地方下载一个JQ添加到我们的项目工程资源路径下。现在根本不需要了,直接引入jar包


springboot-配置文件的使用

1、配置文件的使用

修改配置方式1:src\main\resources\application.properties**

#修改端口号
server.port=8081
#端口号后需额外添加字符
server.servlet.context-path=/demo
@RestController
public class HelloWorld {
    @GetMapping("/hello")
    public String say() {
        return "HelloWorld!";
    }
}

修改配置方式2:src\main\resources\application.yml

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

个人比较喜欢yml

2、切换配置文件

1、多配置文件

src\main\resources\application-dev.yml

server:
  port: 8081

src\main\resources\application-prod.yml

server:
  port: 8080

src\main\resources\application.yml

  • 根据active:来切换配置文件
spring:
  profiles:
    active: prod

 注意active后面写那个就是激活那个配置文件

2、单配置文件(分块)

  • 在单一文件中,可用连续三个连字号(—)区分多个文件。
  • 根据active:来切换配置文件
server:
  port: 8081
spring:
  profiles: prod
---
server:
  port: 8080
spring:
  profiles: dev
---
spring:
  profiles:
    active: prod

spring profiles是配置块的名称。

3、激活指定profile

​ 1、在配置文件中指定 spring.profiles.active=dev

​ 2、命令行:

​ java -jar ***.jar –spring.profiles.active=dev

​ 可以直接在测试的时候,配置传入命令行参数

​ 3、虚拟机参数,在IDEA或Eclipse中的run configuration中可以进行配置

​ -Dspring.profiles.active=dev

4、配置文件加载位置

springboot 启动后扫描以下位置的application.properties或者application.yml文件,

作为Spring boot的默认配置文件

位置说明
–file:./config/项目目录下的config
–file:./项目目录下
–classpath:/config/resources目录下的config
–classpath:/resources目录下

优先级由高到底,高优先级的配置会覆盖低优先级的配置;

SpringBoot会从这四个位置全部加载主配置文件;互补配置

我们还可以通过spring.config.location来改变默认的配置文件位置

项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;

指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;

java -jar ***.jar –spring.config.location=E:/application.yml

从spring的运行日志中可以看到:

Loaded config file 'file:./config/application.yml' (file:./config/application.yml)
Loaded config file 'file:./application.yml' (file:./application.yml)
Loaded config file 'file:/C:/Users/Administrator/Desktop/demo3/target/classes/config/application.yml' (classpath:/config/application.yml)
Loaded config file 'file:/C:/Users/Administrator/Desktop/demo3/target/classes/application.yml' (classpath:/application.yml)

配置文件的加载顺序:

  • ./config/application.yml 项目目录下的config目录下的配置文件
  • ./application.yml 项目目录下的配置文件
  • classpath:/config/application.yml 资源路径下的config 目录下的配置文件
  • classpath:/application.yml 资源路径下的配配置文件

总结:

  1. 先加载的优先级最高,后面的优先级低。
  2. 后面的配置文件中如果有不同的配置项,也会读取进来。

springboot-配置文件详解

1.YML是什么

SpringBoot使用一个全局的配置文件,配置文件名是固定的;

  • application.properties
  • application.yml

配置文件的作用:修改SpringBoot自动配置的默认值;

YAML(YAML Ain’t Markup Language)

YAML A Markup Language:是一个标记语言

YAML isn’t Markup Language:不是一个标记语言

标记语言:

以前的配置文件;大多都使用的是 xxx.xml文件;

YAML:以数据为中心,比json、xml等更适合做配置文件;

  • YAML:配置例子
server:
  port: 8081
  • XML:配置例子
<server>
	<port>8081</port>
</server>

2.YML语法

k:(空格)v:表示一对键值对(空格必须有);

空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的

server:
  port: 8081
  path: /hello

属性和值也是大小写敏感;

字面量

普通的值(数字,字符串,布尔)

k: v 字面量直接来写

字符串默认不用加上单引号或者双引号;

"":双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思
        name:   "zhangsan \n lisi":输出;zhangsan 换行  lisi

'':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据
        name:   ‘zhangsan \n lisi’:输出;zhangsan \n  lisi

总结:

对于字串的值,直接写和加上单引号的效果是一样,字串的内容原样输出,如果要使用特殊的字符的功能,需要加上双引号,比如说:\n如果是再双引号中的就作为换行了。

对象、Map

(属性和值)(键值对):

k: v:在下一行来写对象的属性和值的关系;注意缩进

​ 对象还是k: v的方式

friends:
  lastName: zhangsan
  age: 20

行内写法:

friends: {lastName: zhangsan, age: 18}

数组

(List、Set):

用 - 值表示数组中的一个元素

pets:
 - cat
 - dog
 - pig

行内写法

pets: [cat, dog, pig]

springboot-配置文件的注入

1、单值注入

使用@Value注解注入单个属性的值

  • yml配置文件
swagger:
  title: SpringBoot学习
  description: SpringBoot快速入门
  version: 1.0.0
  name: jenrey
  url: http://jenrey.csdn.net
  email: jenrey@foxmail.com
#server:
#  #端口号
#  port: 8888
person:
  name: jenrey
  age: 24
  • java代码
package com.example.demo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ValueTest {
    @Value("${person.name}")
    private String name;
    @Value("${person.age}")
    private String age;
    Logger log = LoggerFactory.getLogger(ValueTest.class);

    @GetMapping("/value")
    public String user() {
        log.info("name=" + name + ",age=" + age);

        return "Hello 配置文件参数注入";
    }
}

${key} :来引用属性文件中key对应的值

2、批量注入

使用@ConfigurationProperties注解批量注入配置文件中的多个值

  • yml配置文件
person:
  lastName: 大汤圆
  age: 18
  boss: false
  birth: 2017/12/12
  maps: {k1: v1, k2: 12}
  lists:
  - 张三
  - 李四
  dog:
    name: 小奶狗
    age: 2

@Data是一个lomlok插件,免去了getter/setter和toString这些繁琐的东西

在POM文件的节点中间添加

  <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.4</version>
      <scope>provided</scope>
  </dependency>
  • 新建一个Person的Pojo类,代码如下 
package com.example.demo.pojo;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

//封装配置文件中person中的数据
@ConfigurationProperties(prefix = "person")
@Component
@Data
public class Person {
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map<String, Object> maps;
    private List<String> lists;
    private Dog dog;
}
  • 新建一个Dog的Pojo类,代码如下
package com.example.demo.pojo;

import lombok.Data;

@Data
public class Dog {
    private String name;
    private Integer age;
}

使用@ConfigurationProperties注解必须同时添加@Component将当前的配置类放入IOC容器中

在编写yml文件的时候没有出现属性提示:

我们可以导入配置文件处理器,以后编写配置就有提示了

<!--导入配置文件处理器,配置文件进行绑定就会有提示-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

发现变成了下面的灰色

我们重新启动IDEA,点击一下 隐藏通知 就行啦。

  • 测试代码
package com.example.demo.controller;

import com.example.demo.pojo.Person;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigurationPropertiesTest {
    Logger log = LoggerFactory.getLogger(ConfigurationPropertiesTest.class);
    //把容器里的装配进来
    @Autowired
    private Person person;

    @GetMapping("/test")
    public String hello() {
        log.info(person.toString());//toString()方法我们不用写,@Data自动帮我们写了
        return "hello";
    }
}
  • 控制台的输出
Person(lastName=大汤圆, age=18, boss=false, birth=Tue Dec 12 00:00:00 CST 2017, maps={k1=v1, k2=12}, lists=[张三, 李四], dog=Dog(name=小奶狗, age=2))

javaBean:

  • 将配置文件中配置的每一个属性的值,映射到这个组件中
  • @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
  • prefix = “person”:配置文件中哪个下面的所有属性进行一一映射
  • 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能;
  • @Data是一个插件,,免去了getter/setter和toString这些繁琐的东西

3、两种注入的区别

@Value获取值和@ConfigurationProperties获取值的区别

 @ConfigurationProperties@Value
功能批量注入配置文件中的属性一个个指定
松散绑定(松散语法)支持不支持
SpEL: #{}不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持

松散语法绑定:last_name = last-name = lastName 他们取的值都是相同的

配置文件yml还是properties他们都能获取到值;

总结:

  • 如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
  • 如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;

4、注入值的数据校验

@ConfigurationProperties(prefix = "person")
@Component
@Data
@Validated //数据校验
public class Person {

    @Email(message = "用户名必须是一个正确的邮箱格式")
    private String lastName;
    @Max(value = 200,message = "年龄不能超过200岁")
    @Min(value = 0,message = "年龄必须大于0岁")
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map<String,Object> maps;
    private List<String> lists;
    private Dog dog;

}

经过刚才的测试得出,两个注解不能同时作用在一个属性上。


springboot-其他配置文件

1、@PropertySource

@PropertySource:加载指定的配置文件;

@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
   	// lastName必须是邮箱格式
   	// @Email
    // @Value("${person.last-name}")
    private String lastName;
    // @Value("#{11*2}")
    private Integer age;
    // @Value("true")
    private Boolean boss;

请注意 [字串,bool,时间,列表可以注入],map不能注入,

简单的数据类型Spring注入数据后进行了类型转换

断点查看可以知道注入的数据

person.lastName=hehe@foxmail.com
person.age=18
person.boss=false
person.birth=2017/12/12
person.lists=lisi,zhaoliu
People(lastName=hehe@foxmail.com, age=18, pets=null, boss=false, birth=Tue Dec 12 00:00:00 CST 2017, lists=[[lisi, zhaoliu]])

IDEA设置*.properties文件的默认编码

Settings
–> Editor
–> File Encoding
–> Properties Files(*.properties)
–> Default encoding for properties files: UTF-8
–> OK

2、@ImportResource

@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效;

想让Spring的配置文件生效,@ImportResource标注在一个配置类上

@ImportResource(locations = {"classpath:beans.xml"})
@SpringBootApplication
public class SpringbootApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootApplication.class, args);
	}
}
  • Spring的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="p123" class="site.accp.demo7.pojo.People">
        <property name="lastName" value="123"/>
    </bean>
</beans>
  • 测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class Demo7ApplicationTests {

    @Autowired
    ApplicationContext ioc;

    @Test
    public void contextLoads() {
        boolean p123 = ioc.containsBean("p123");
        System.out.println(p123);
    }

}

3、@Bean

SpringBoot推荐使用全注解的方式给容器中添加组件

1、配置类@Configuration –> Spring配置文件

2、使用@Bean给容器中添加组件

/**
 * @Configuration:指明当前类是一个配置类;就是来替代之前的Spring配置文件
 * 在配置文件中用<bean><bean/>标签添加组件
 */
@Configuration
public class MyAppConfig {

    // 将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名
    @Bean
    public HelloService helloService02(){
        System.out.println("配置类@Bean给容器中添加组件了...");
        return new HelloService();
    }
}

测试:

@Test
public void testHelloService() {
    boolean b = ioc.containsBean("helloService02");
    System.out.println(b); // true
}

输出:配置类@Bean给容器中添加组件了… 同时返回true

4、配置文件占位符

  • 随机数
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}
  • 占位符获取之前配置的值

如果没有可以使用的:指定默认值

person.last-name=张三${random.uuid}
person.age=${random.int}
person.birth=2017/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
# 没有取到:后面是默认值
person.dog.name=${person.hello:hello}_dog
person.dog.age=15

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值