Springboot自学笔记

git源码

简介

SpringBoot官网

SpringBoot是由Pivotal团队在2013年开始研发、2014年4月发布第一个版本的全新开源的轻量级框架。它基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。

微服务

微服务:一个项目 可以由多个 小型服务构成(微服务)

可更新可替代性比较强

spring boot可以快速开发 微服务模块

  1. 简化j2ee开发
  2. 整个spring技术栈的整合(整合springmvc spring)
  3. 整个j2ee技术的整合(整合mybatis redis)

配置java环境变量

  • JAVA_HOME: jdk根目录
  • path:%JAVA_HOME%\bin
  • classpath:.%JAVA_HOME%\lib%JAVA_HOME%\lib\tools.jar

配置maven环境变量

  • MAVEN_HOME: maven根目录
  • path: maven根目录\bin
  • 配置Maven本地仓库: mvn根目录/conf/setting.xml : <localRepository>C:/workplace/jar/mavenrep</localRepository>
  • 在STS中配置mvn:

    window->preference->搜maven ,installations/user settings
    

简单springboot项目

  • 去官网生成springbootxiangmu官网

  • STS 导入项目(Existing maven项目)

  • 右键运行HelloWorldApplication.java –run java application

    出现springboot和对应的版本号说明springboot配置好了

目录结构

  • java:java代码
  • resources/static:静态资源(js css 图片 音频 视频)
  • resources/templates:模板文件(模版引擎freemarker ,thymeleaf;默认不支持jsp)
  • resources/application.properties: 配置文件

    springboot开发WEB程序

以前:webContext–web.xml–war–tomcat

spring boot内置了tomcat,并且不需要打成war再执行。


@Controller
public class HelloWorldController {
    //页面直接打印这些文字
    @ResponseBody
    @RequestMapping("helloWorld")
    public String helloWorld() {
        return "hello world;hello spring boot";
    }
}

直接运行HelloWorldApplication.java –run java

访问

http://localhost:8080/helloWorld

可以发现此时没有运行tomcat就能运行

可以在appication.properties对端口号等服务端信息进行配置

server.port=8888

spring boot将各个应用/三方框架 设置成了一个个“场景”stater,以后要用哪个,只需要引入那个场景即可。 选完之后,spring boot就会将 该场景所需要的所有依赖 自动注入。

官方starter介绍

例如 选择 web,spring boot就会将web相关的依赖(tomcat json) 全部引入本项目

版本仲裁中心

pom.xml中

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

连续进入,就会发现里面配置了各个jar包的版本

主配置类

HellowordApplication.java中含有注解

@SpringBootApplication

spring boot的主配置类

该注解包含了许多注解例:

  • @SpringBootConfiguration

    包含@Configuration,表示”配置类”(用来代替配置文件):

    1. 该类是一个配置类
    2. 加了@Configuration注解的类,会自动纳入Spring 容器 (@Component)

      @Configuration
      public class A//表示A是一个 用于 配置的类
      {
      }
      
  • @EnableAutoConfiguration

    使spring boot可以自动配置 :(以前做spring,mybatis等项目时需要写很多配置文件,但是这里我们发现我们并没有写配置文件)约定优于配置(之前已经约定好了,所以没有进行配置)

    • @AutoConfigurationPackage

      可以找到@SpringBootApplication所在类的包 ,

      作用:就会将该包及所有的子包 全部纳入spring容器

      spring boot自动配置自动将@SpringBootApplication所在类的包及其子包纳入spring容器中

    • @Import(AutoConfigurationImportSelector.class

      AutoConfigurationImportSelector类中的selectImports方法在spring boot在启动时,会根据META-INF/spring.factories找到相应的三方依赖,并将这些依赖引入本项目

总结:

编写项目时,一般会 对自己写的代码以及三方依赖 进行配置。但是spring boot可以自动进行配置:

  • 自己写的代码

    spring boot通过@SpringBootConfiguration自动帮我们配置;

  • 三方依赖

    通过spring-boot-autoconfigure-2.0.3.RELEASE.jar中的META-INF/spring.factories进行声明,然后通过@EnableAutoConfiguration开启使用即可

    spring-boot-autoconfigure-2.0.3.RELEASE.jar包中 包含了 J2EE整合体系中 需要的依赖。

如何自动装配

研究

org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,

通过观察该源码 发现:

@Configuration

标识此类是一个配置类 、将此类纳入springioc容器

@EnableConfigurationProperties(HttpEncodingProperties.class)

通过HttpEncodingProperties将编码设置为了UTF_8 (即自动装配为UTF_8)

如何修改改编码

通过改HttpEncodingProperties的 predfix+属性名 进行修改 (配置文件中,yml/properties)

spring.http.encoding.charset=ISO-8859-1

即:该注解给了默认编码utf8,并且提供了prefix+属性名 的方式 供我们修改编码。

当满足以下条件(@Conditional)时才会被加载

@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)  

当它是一个servlet时成立

@ConditionalOnClass(CharacterEncodingFilter.class)      

当它有CharacterEncodingFilter这个类的时候成立

@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)

当属性满足要求时,此条件成立 :要求 :如果没有配置spring.http.encoding.enabled=xxx, 则成立。

总结:

  1. 每一个XxAutoConfiguration都有很多条件@ConditionalOnXxx,当这些条件都满足时,则此配置自动装配生效(utf-8)。

    但是我们可以手工修改改 自动装配:XxxProperties文件中的

    prefix.属性名=value 
    

    conditional类型

  2. 全局配置文件中的key, 来源于某个Properties文件中的 prefix+属性名

    Springboot通过XxAutoConfiguration实现自动装配 ,修改默认值 XxxProperties( prefix+属性名)

如何知道 spring boot开启了哪些自动装配、禁止了哪些自动装配:application.properties中添加

debug=true
  • Positive matches列表 表示 spring boot自动开启的装配
  • Negative matches列表 表示spring boot在此时 并没有启用的自动装配。

配置文件

作用:spring boot 自动配置(约定,8080 ).可以使用配置文件 对默认的配置 进行修改

默认全局配置文件:

  • application.properties

    k=v

    或行内写法(k: v,)

  • application.yml

    yaml ain’t myarkup language ,不是一个标记文档

yaml:不是一个标记文档

server:
    port: 8882
    path: /a/b/c

xml:是一个标记文档

<server>
    <port>8882</port>
    <path>/a/b/c</path>
</server>

赋值

通过yaml给对象注入值:

注意: 1. k:空格v
2. 通过垂直对齐 指定层次关系
3. 默认可以不写引号; ““会将其中的转义符进行转义,其他不会

行内写法

[Set/List/数组] 

{map,对象类型的属性}

并且 []可省,{}不能省

写法一:普通写法

student: 
    name: zs
    age: 23
    sex: true
    birthday: 2019/02/02
    location:     
      province: 陕西1
      city: 西安1
      zone: 莲湖区1
    hobbies: 
      - 足球
      - 篮球
    skills: 
      - 吃喝
      - 玩乐
    pet: 
      nickname: wc
      strain: hsq

写法二:行内写法

student:
  uname: x   
  name: ${student.user.name2:无名}
  #age: 23
  sex: true
  birthday: 2019/02/12
  location: {province: 陕西,city: 西安, zone: 莲湖区}
  hobbies: [足球2,篮球22]
  skills: [编程3,金融33]
  pet: {nick-name: wc555,strain: hsq}
  email: 157468995@qq.com
public class Pet {
	private String nickname;
	private String strain;
}
@Component
@ConfigurationProperties(prefix = "student")
public class Student {
	private String name;
	private int age;
	private boolean sex;
	private Date birthday;
	private Map<String ,Object> location;
	private List<String> skills;
	private String[] hobbies;
	private Pet pet;
}

@ConfigurationProperties(prefix="student")下面出现黄色警告时,单击add xxx,会在pom.xml中增加依赖(元数据的提示依赖)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

通过application.properties对属性进行赋值

student.name=ls
student.age=23

yml与properties两种方式的赋值可以互补使用

通过@Value赋值

在Student.java中使用@Value注解进行赋值

@Value("33")
private int age ;

此时不再需要使用@ConfigurationProperties(prefix=“student”)注解,该注解是在.yml和.properties文件中赋值时使用

小结

@ConfigurationProperties(yml/properties[优先级高])  
@Value("xx") 二者可以互补

选项 @ConfigurationProperties) @Value
注值 批量注入 单个
松散语法 支持 不支持
SpEL 不支持 支持
JSR303数据校验 支持 不支持
注入复杂类型 支持 不支持

松散语法:驼峰命名法与xx-xx命名方式转换stuName--stu-name

SpEL:LspringEL:

@Value("${student.uname}") 
private String userName; 

在文件中赋值,通过el语法取值

JSR303数据校验

@Component //将此Javabean
@ConfigurationProperties(prefix="student")
@Validated//开启jsr303数据校验的注解
public class Student {
    @Email
    private String email ;
}

简单类型:(8个基本类型/String/Date)

@PropertySource

默认会加载application.properties/application.yml文件中的数据;如果数据不在这两个文件时,需要借助它指定。

例如

@Component //将此Javabean
@ConfigurationProperties(prefix="student")
@PropertySource(value={"classpath:conf.yml"})
public class Student {
    @Value("safasd")
}

通过注解@PropertySource(value={"classpath:conf.yml"})加载conf.properties文件中的数据;

通过注解@PropertySource(value={"classpath:conf.yml"})加载conf.properties文件中的数据;

但是,@PropertySource只能加载properties,不能加载yml

@ImportResource

spring boot自动装配/自动配置.

spring等配置文件 默认会被spring boot自动给配置好。

如果要自己编写spring等配置文件, spring boot能否识别?

默认不识别。 

如果需要识别,则需要在spring boot主配置类上 通过@ImportResource指定配置文件的路径

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

但是不推荐手写spring配置文件。

配置:xml配置文件,通过注解配置(推荐)。

spring boot推荐时候用注解方式进行配置:写类,@Configuration @Bean

示例:

//配置类(等价于spring.xml)
@Configuration
public class AppConfig {
    @Bean		
    public StudentService stuService(){//<bean  id="xxxxxxxxxxxxx">  方法名
        StudentService stuService = new StudentService();
//		StudentDao stuDao = new StudentDao()  ;
//		stuService.setStudentDao(stuDao);
        return stuService;//返回值 <bean  class="xxxxxxxxxxxxx">
    }
}

spring boot全局配置文件中的 占位符表达式

$ {random.uuid}:uuid
$ {random.value}:随机字符串
$ {random.int} :随机整型数
$ {random.long}:随机长整型数
$ {random.int(10)}:10以内的整型数
$ {random.int[1024,65536]}:指定随机数范围

引用变量值

.properties文件中

student.user.name=zs

.yml中引用

${student.user.name}
${student.user.name:ls}可以指定默认值

两个文件中的值可以互相引用

application.properties中没有提示的话 在pom.xml中添加

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

多环境的切换(profile)

properties文件

默认spring boot会读取application.properties

多个:

application-环境名.properties
application-dev.properties
application-test.properties

如果要选择某一个具体的环境: application.properties中指定:(环境名:dev,test)

spring.profiles.active=环境名

如果将application.properties注释掉,spring boot仍然会读取其他appilcation-环境名.properties中的配置。并且properties的优先级高于yml

yml

环境与环境之间通过—隔开

# 主环境
server:
  port: 8883
#指定环境
#spring:
#  profiles:
#    active: dev
---
#环境一
server:
  port: 8884
spring:
  profiles: dev

--- 
#环境二 
server:
  port: 8885
spring:
  profiles: test

动态切换环境

  1. 通过运行参数指定环境

    • STS(Eclipse) :

      右键–Run Configuration - Argument(Java Application中指定项目) - program Argument

      --spring.profiles.active=环境名
      

    命令行方式:

    项目打jar包:
    
    项目右键-->run as -->maven build...-->
    Goals:输入
    
        package
    -->run-->在src同级目录target下会出现jar包
    
    cmd到文件目录,执行
    
      java -jar 项目名.jar --spring.profiles.active=环境名
    
  2. 通过jvm参数指定环境

    STS(Eclipse) :Run Configuration - Argument - VM arguments

    -Dspring.profiles.active=环境名
    

配置文件的位置

项目内部的配置文件:

properties和yml中的配置,相互补充;如果冲突,则properties优先级高。

spring boot默认能够读取的application.properties/application.yml,这2个文件 可以存在于以下4个地方:

  1. file:项目根目录/config

  2. file:项目根目录

  3. classpath:项目根目录/config

  4. classpath:项目根目录

注意:

  1. 如果某项配置冲突,则优先级从上往下
  2. 如果不冲突,则互补结合使用

配置项目名:

properties文件中

server.servlet.context-path=/boot

项目外部的配置文件: (补救)

在项目Run configuration ,argumenets:

--spring.config.location=D:/application.properties

如果 同一个配置 同时存在于 内部配置文件 和外部配置文件,则外部>内部

命令行方式

打包文件

clean  package

先清理后打包

cmd到jar路径,通过命令行 调用外部配置文件

java -jar xxx.jar --spring.config.location=D:/application.properties

项目运行参数

(补救)(配置与配置直接可以加空格隔开)

在项目Run configuration ,argumenets:

--server.port=8883

通过命令行修改配置参数

cmd到jar包

java -jar  项目.jar  --server.port=8883

多个地方配置时,如果冲突,优先级:

命令参数(调用外部的配置文件 > 运行参数 )>内部文件 (properties>yaml)

官网对多配置时的顺序说明:

日志

日志框架: UCL 、JUL 、jboss-logging、logback、log4j、log4j2、slf4j…

spring boot默认选用slf4j,logback,spring boot默认帮我们配置好了日志,我们直接使用即可。

使用

Logger logger =  LoggerFactory.getLogger(HelloWorldApplicationTests.class  );//获取日志对象
@Test
public void testLog(){//日志级别
    logger.trace("trace********");
    logger.debug("debug********");
    logger.info("info*******");
    logger.warn("warn******");
    logger.error("error****");
}

日志级别:(LogLevel类中)

TRACE< DEBUG< INFO<WARN< ERROR< FATAL<OFF

springboot默认的日志级别是info(即只打印 info及之后级别的信息);

也可以自定义级别:全局配置文件中

logging.level.主配置类所在包=级别

logging.level.org.yq.HelloWorld=warn

日志存储

可以通过配置 将日志信息 存储到文件中

logging.file=springboot.log 

存储到了项目的根目录中的springboot.log

也可以指定 具体的日志路径:

logging.file=D:/springboot.log

也可以存储到一个 文件夹中 ,

logging.path=D:/log/

并且默认的文件名是spring.log

指定日志显示格式:

  1. 日志显示在console中

    logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
    
    %d:             日期时间
    %thread:       线程名
    %-5level:      显示日志级别,-5表示从左显示5个字符宽度
    %logger{50} :   设置日志长度  
    %msg:          日志消息
    %n :           回车
    
  2. 日志显示在文件中

    logging.pattern.file=%d{yyyy-MM-dd} ** [%thread] ** %-5level ** %logger{50}** %msg%n
    

默认的日志格式,是在spring-boot.jar包中 相应包的xml文件中进行配置。 /org/springframework/boot/logging/

日志的具体使用规范:官方说明

springboot开发Web项目

(静态资源 html css js )

新建项目(sts)

new – spring starer Project –设置(选择 需要的场景,web)

静态资源存放路径

spring boot是一个jar,因此 静态资源就不是再存放到 webapps中,存放在哪里?

静态资源的存放路径 通过WebMvcAutoConfiguration类-addResourceHandlers()指定为:/webjars/

spring boot将静态资源存入到jar包中,引入:以后需要引入静态资源时只需要像maven那样去官网找到文件然后添加依赖即可

<!--以前引入js等静态资源,是将这些资源下载并且手工放入到webapp目录中;而springboot将这些静态资源 直接以jar文件(maven)的形式引入项目-->
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery-ui</artifactId>
    <version>1.12.1</version>
</dependency>

webjars官网

使用

访问:从Jar目录结构的webjars开始写:http://localhost:8080/webjars/jquery/3.3.1-1/jquery.js

将自定义静态资源放入项目

如何自己写 静态资源,如何放到如spring boot中?

  1. 将自己写的 静态资源->jar,同上(不推荐);

  2. 自定扫描方式(推荐):

spring boot约定: spring boot将一些目录结构设置成静态资源存放目录,我们的静态资源直接放入这些目录即可,目录在哪里?

ResourceProperties类中的CLASSPATH_RESOURCE_LOCATIONS中设置:

{
    "classpath:/META-INF/resources/", "classpath:/resources/",
    "classpath:/static/", "classpath:/public/" 
}

注意:在以上目录存放资源文件后,访问时 不需要加前缀,直接访问即可:http://localhost:8080/world.html

设置欢迎页

WebMvcAutoConfiguration类中的welcomePageHandlerMapping() –>getIndexHtml() –> location + "index.html" ,即任意一个静态资源目录中的 index.html就是欢迎页

网站中,网页标签的Logo是固定名字 : favicon.ico

自定义 favicon.ico

阅读 源码得知:只需要将 favicon.ico文件放入任意静态资源目录中即可。

总结:

  1. 通过源码发现静态资源的目录
  2. 用静态资源:只需要将静态资源放入 以上目录即可
  3. 其他特定的文件(欢迎页、ico),只需要 根据约定(index.html favicon.ico) 放入该目录即可

自定义静态资源目录

如何自定义静态资源目录(Properties文件中的 prefix+属性) :

spring.resources.static-locations=classpath:/res/, classpath:/img/

以上就将静态资源目录设置为了classpath:/res/, classpath:/img/

注意:自定义静态资源目录后 以前默认的目录会失效

动态资源:

JSP(spring boot默认不支持)

推荐:模板引擎 thymeleaf

网页= 模板+数据

引入thymeleaf

到官网查询 thymeleaf的依赖官网

使用thymeleaf

thymeleaf官网

代码在哪里写?

查找自动装配jar包spring-boot-autoconfigure.jar,去里面查找响应的依赖找到XxProperties注解类,查看默认值

今后查看默认值只需要查看

XXXAutoCongifutation 、
XxProperties

通过ThymeleafProperties源码得知:

使用thymeleaf只需要将 文件放入目录:"classpath:/templates/"; 文件的后缀: .html;

使用

引入命名空间

<html xmlns:th="http://www.thymeleaf.org">

引入标签

<p th:text="${welcome}">Welcome to our grocery store!</p>

控制器传值

@RequestMapping("/welcome")
public String welcome(Map<String,Object> map) {
    map.put("welcome", "welcome--hahahhaha");
    return "welcome";
}

以上,先从${welcome}中取值,如果有 则直接显示;如果没有,则在显示welcome to thymeleaf....

注意:在以前传统的web项目中:静态资源修改后 是不需要重启的;但是在spring boot项目中,修改后 需要重启。

th就是替换原有html的值:th:html属性名=值 ;

<p id="pid" class="pclass"  th:id="${welcome}" th:class="${welcome}"  th:text="${welcome}">welcome to thymeleaf....</p>
th:xx  (参见第10章  Attrubite Pre....)
th:text   获取文本值(不转义) 显示<h1>hello</h1>
th:utext  获取文本值    显示 将hello 渲染为h1后的效果

符号

th:text="${welcome}" 

除了$以外 其他符号? 查看第四章 Standard Express….

<div th:each="prod : ${prods}">
    <h4 th:text="${prod.name}">11</h4>
    <h4 th:text="${prod.price}">11</h4>
    <h4 th:text="${prod.inStock}">11</h4>
</div>
@RequestMapping("/welcome1")
public String welcome1(Map<String,Object> map) {
    List<Product> prods = new ArrayList<>(); 
    prods.add(new Product("a",1000,100));
    prods.add(new Product("b",1001,101));
    prods.add(new Product("c",1002,102));
    prods.add(new Product("d",1003,103));
    map.put("prods", prods);
    return "welcome";
}

Spring boot整合JSP开发

之前spring boot默认 自带一个内置的tomcat,不需要打war包,直接通过Jar即可运行。但是,如果要整合jsp开发,就需要 单独配置一个 外置的tomcat ,需要打war包。

Spring boot整合JSP开发步骤:

  1. 新建spring boot项目,war

注意:

  <dependency>
  	<groupId>org.springframework.boot</groupId>
  	<artifactId>spring-boot-starter-tomcat</artifactId>
  	<scope>provided</scope>
  </dependency>

provided:意思是 将项目打包时,不需要将内置的tomcat一起打包。

  1. 建立基本的web项目所需要的目录结构

    webapps/WEB-INF(需要)
    webapps/WEB-INF/web.xml (不需要)
    webapps/index.jsp
    
  2. 创建tomcat实例、部署项目

    访问:

    域名:端口/项目名/文件名

    http://localhost:8080/SbJSP/index.jsp
    

分析:

如果是一个war包的spring boot项目,在启动服务器tomcat时, 会自动调用ServletInitializer类中 的configure方法,configure方法会调用spring boot的主配置类 从而启动spring boot;

即在启动tomcat服务器时 会

  1. 启动tomcat
  2. 启动spring boot