麻绳先生

做一些记录性的工作

spring-boot和web开发

web开发

如何使用spring boot:

  1. 创建spring boot应用,选中需要的模块;
  2. spring boot已经默认将这些场景配置好,只需要在配置文件中指定少量配置就可与运行;
  3. 编写业务代码;

自动配置原理

webjars和静态资源映射规则

  1. 所有/webjars/**,都去classpath:/META-INF/resources/webjars查找资源;
    webjars:以jar包方式引入静态资源。

  2. “/**”访问当前项目的任何资源,静态资源文件夹

    1
    2
    3
    4
    5
    "classpath:/MEAT-INF/resources/",
    "classpath:/resources/",
    "calsspath:/static/",
    "calsspath:/puclic/",
    "/":当前目录的根目录
  3. 欢迎页:静态资源文件夹下的所有index.html页面,被”/**”映射;

  4. 所有的**/favicon.ico都是在静态资源文件夹下查找;

模板引擎

JSP、

1
2
3
4
5
6
7
8
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<properties>
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>
</properties>

thymeleaf

导入语法空间

thymeleaf语法规则

  • 片段包含:jsp:include
    • th:insert
    • th:replace
  • 遍历:c:forEach
    • th:each
  • 条件判断c:if
    • th:if
    • th:unless
    • th:switch
    • th:case
  • 声明变量c:set
    • th:object
    • th:with
  • 任意属性修改支持prepend,append
    • th:attr
    • th:attrprepend
    • th:attrappend
  • 修改指定属性默认值
    • th:value
    • th:href
    • th:src
  • 修改标签体内容
    • th:text不转义
    • th:utext转义
  • 声明片段
    • th:fragment

thymeleaf表达式

  • Simple expressions:
    • Variable Expressions: ${…}
    • Selection Variable Expressions: *{…}
    • Message Expressions: #{…}
    • Link URL Expressions: @{…}
    • Fragment Expressions: ~{…}
  • Literals
    • Text literals: ‘one text’ , ‘Another one!’ ,…
    • Number literals: 0 , 34 , 3.0 , 12.3 ,…
    • Boolean literals: true , false
    • Null literal: null
    • Literal tokens: one , sometext , main ,…
  • Text operations:
    • String concatenation: +
    • Literal substitutions: |The name is ${name}|
  • Arithmetic operations:
    • Binary operators: + , - , * , / , %
    • Minus sign (unary operator): -
  • Boolean operations:
    • Binary operators: and , or
    • Boolean negation (unary operator): ! , not
  • Comparisons and equality:
    • Comparators: > , < , >= , <= ( gt , lt , ge , le )
    • Equality operators: == , != ( eq , ne )
  • Conditional operators:
    • If-then: (if) ? (then)
    • If-then-else: (if) ? (then) : (else)
    • Default: (value) ?: (defaultvalue)
  • Special tokens:
    • No-Operation: _

Spring Boot自动配置Spring MVC

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans;
  • Support for serving static resourcces, including support for Webjars;
  • Automatic registration of Converter, GenericConverter, Formatter beans;
  • Support for HttpMessageConerters;
  • Automatic registration of MessageCodeResolver;
  • Static index.html support;
  • Custom Favicon support;
  • Automatic use of a ConfigurableWebBindingInitializer bean;

修改Spring Boot默认配置

扩展Spring MVC

Tips

国际化

默认的区域信息是通过浏览器请求报文获取的。可以通过链接提交区域信息。
自己的信息解析器需要实现Localeresolver。

  1. 编写国际化配置文件,抽取页面需要配置的国际化信息;
  2. 使用ResourceBundleMessageSource管理国际化资源信息;
  3. 在页面使用fml:message获取国际化内容;
  4. 可以自己编写区域信息解析器,替换Spring Boot默认的解析器ResourceBundleMessageSource;

模板引擎要实时生效,需要禁用模板缓存,页面修改要ctrl+F9重新编译

登陆状态检查需要拦截器

thymeleaf公共页面元素抽取

  1. 抽取公共片段
  2. 引入公共片段
  3. 不同替换效果有th:insert、th:replace、th:include

错误处理的自动配置

可以参照ErrorMVCAutoConfiguration;容器中有如下组件:

  1. DefaultErrorAttributes
  2. BasicErrorController
  3. ErrorPageCustomizer
  4. DefaultErrorViewResolver

注册Servlet、Filter、Linstener

Spring Boot默认是以jar包的方式启动嵌入式的Servlet容器来启动Spring Boot的web应用,没有web.xml文件;
注册三大组件使用ServletRegistrationBean, FilterRegistrationBean, ServletListenerRegistrationBean。

其他嵌入式Servlet容器

Jetty

适合长连接

Undertow

后置处理器会获取所有容器中的定制器,以此配置Servlet容器,自己定义容器就是将自定义的定制器加到Bean工厂中。

嵌入式Servlet容器启动原理

  1. Spring Boot应用启动运行run方法;
  2. refreshContext(context);Spring Boot刷新IOC容器,创建IOC容器对象,并初始化容器,创建容器中的每一个组件,还判断了是否是web应用;
  3. refresh(context);刷新刚才创建好的ioc容器;
  4. onRefresh();web的IOC容器重写了onRefresh方法;
  5. web IOC容器会创建嵌入式的Servlet容器;createEmbeddedServletContainer();
  6. 获取嵌入式的Servlet容器工厂;TomcatEmbeddedServletContainerFactory创建对象,后置处理器随后获取所有的定制器来定制Servlet容器的相关配置;
  7. 使用容器工厂获取嵌入式的Servlet容器;
  8. 嵌入式的Servlet容器创建对象并启动Servlet容器;先启动嵌入式的Servlet容器,再将IOC容器中剩下的对象获取;

使用外置的Servlet容器

嵌入式Servlet容器优点在于简单、便携,缺点在于默认不支持JSP,优化定制不够复杂;使用定制器、自己编写嵌入式Servlet容器的创建工厂;

  1. 必须创建一个war项目,利用idea创建目录结构;
  2. 将嵌入式的Tomcat指定为provided;
  3. 必须编写一个SpringBootServletInitializer的子类,并调用configure方法;
  4. 启动tomcat;

YAML

  1. YAML Ain’t Markup Language
  2. YAML A Markup Language

.yml是YAML语言的文件,以数据为中心,比json、xml更适合做配置文件。

参考语法规范http://www.yaml.org

1
2
server:
port: 8081

基本语法

key:(空格)value:表示一对键值对,空格是必须的;

以空格的缩进来控制层级关系,只要左对齐,就认为是同一层级。

值的写法

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

key:(空格)value:字面直接写

  • 字符串默认不用引号
  • 双引号和单引号有区别,前者会对特殊字符转义,后者只会当作普通字符

数组(list、set)

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

1
2
3
4
pets:
- cat
- dog
- pig

行内写法

1
pets: [cat,dog,pig]

对象、Map(属性和值)

方法和前文一致

1
2
3
4
friend:
firstname: zhang
lastname: san
telphone: 136545646

行内写法

1
friend: {firstname: zhang,lastname: san,telphone: 136545646}

解析yml配置文件

spring-boot解析yml文件需要使用注解@ConfigurationProperties(prefix = “index-id””)

ConfigurationProperties和value有区别

默认从全局配置文件中获取值

@PropertySource

解析非全局配置文件

@PropertySource(value = “calsspath:example.properties”)

@ImportResource

@ImportResource导入spring配置文件,使配置文件内容生效。

@ImportResource(location = “classpath:beans.xml”)

springboot推荐的像容器中添加组件的方式:
使用全注解的方式。
使用@Configuration指明一个配置类。

gradle

基于JVM的构建工具,有一些特性

  • 和maven一样基于约定优于配置的构建框架
  • 强大的多工程构建支持
  • 强大的依赖管理,基于apachelvy
  • 支持已有的maven和ivy仓库
  • 支持传递性依赖管理,不需要远程仓库或pom.xml等配置文件

gradle安装

先决条件

  • gradle需要1.5或更高版本的JDK;
  • gradle自带groovy库,忽略已安装grooy

配置环境变量

  • 将GRADLE_HOME/bin添加到PATH变量中
  • 使用命令gradle -v命令测试

构建基础

task

project

groovy中的闭包

就是一段代码块,在gradle中,主要将闭包作为参数使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//定义一个闭包
def bb = {
println "hello, bb"
}
//定义一个方法,方法的参数是闭包类型
def method(Closure closure){
closure()
}
//调用该方法
method(bb)

//定义一个闭包,带参数
def closure2 = {
v -> println "hello, ${v}"
}

//定义一个需要闭包的方法
def method2(Closure closure){
closure("world")
}

method2(closure2)

拆分

聚合

1
2
3
allproject{

}

maven

目前存在的问题

  1. 一个项目就是一个工程
    如果项目非常庞大,就不适用package来划分模块,最好每一个模块对应一个工程,利于分工协作。借助于maven就可以将一个项目拆分为多个工程。
  2. 项目中需要的jar包需要手动管理
    同样的文件出现在不同的工程中,浪费存储,让文件结构冗余。
  3. jar包来源复杂,难以维护
  4. jar包依赖的其他文件仍需手动管理

什么是maven

是一款服务于java平台的自动化构建工具。

什么是构建

以“java源文件”、“框架配置文件”、JSP、HTML、图片等资源为原材料产生一个可运行的项目的过程。

  • 清理:将之前编译生成的字节码文件删除,为下一次编译做准备
  • 编译:将java源程序编程为class字节码文件
  • 测试:自动测试,自动调用junit程序
  • 报告:测试程序执行的结果
  • 打包:动态web工程war包,java工程jar包
  • 安装:maven特定的概念,将打包得到的文件复制到仓库中指定位置
  • 部署:将动态web工程生成的war包复制到servlet容器的指定目录下

安装maven核心程序

  • 检查JAVA_HOME环境变量
  • 解压maven核心程序压缩包,英文无空格目录
  • 配置maven相关环境变量
    • MAVEN_HOME或M2_HOME(bin目录上一级)
    • path(通常带bin目录)
  • 运行mvn -v验证配置

maven核心概念

约定的目录

  • 根目录:工程名
    • 以配置的方式告诉框架自定义文件:classpath:spring-content.xml
  • src目录:存放源码
  • pom.xml:maven工程核心配置文件
  • main目录:存放主程序
  • test目录:存放测试程序
  • java目录:存放java源码
  • resources目录:存放框架或其他工具的配置文件

约定大于配置,配置大于编码

POM

含义:project object model项目对象模型

坐标(gav)

  • groupid:公司组织域名倒序+项目名
  • artifactid:模块名
  • version:版本

依赖

  • 对于自己的maven工程,使用install命令将其安装到仓库。
  • 依赖的范围
    • compile:对主程序有效,对测试程序有效,参与打包
    • test:对主程序无效,对测试程序有效,不参与打包
    • provided:对主程序有效,对测试程序有效,不参与打包,不参与部署,例如servlet-api.jar
  • scope
  • 只有compile范围的依赖可以传递
  • exclusions用于排除依赖

依赖的原则

  • 作用:解决模块工程之间的jar包冲突
    • 最短路路径优先
    • 路径相同时先声明者优先,指的是dependency标签的声明顺序

统一管理依赖的版本号

  • properties标签,后跟依赖的id
  • 通过${依赖的id}访问版本号
  • 由于test范围的依赖不能传递,所以必然分散在各个模块工程中,导致不一致问题
    • 解决思路:将依赖统一提取到父工程中,在子工程中声明依赖时不指定版本,以父工程中统一的设定为准,方便维护
    1. 创建一个maven工程为父工程,注意打包方式为pom
    2. 在子工程中声明对父工程的引用
    3. 将子工程中的坐标中与父工程坐标中重复的内容删除
    4. 在父工程中统一管理依赖
    5. 子工程中删除依赖的版本号

子工程要首先install父工程

仓库

生命周期/插件/目标

  • 各个构建环节执行的顺序是既定的;
  • maven核心程序中定义了抽象的生命周期;
  • 不论执行哪个命令,maven都会从生命周期最开始的位置执行;

继承

聚合

一键安装各个模块工程
在一个总的聚合工程中配置各个参与聚合的模块

1
2
3
4
5
<modules>
<module></module>
<module></module>
<module></module>
</modules>

常用maven命令

首先进入pom.xml目录

  • mvn clean:清理
  • mvn compile:编译主程序
  • mvn test-compile:编译测试程序
  • mvn test:执行测试
  • mvn package:打包
  • mvn install:安装
  • mvn site:生成站点

自动部署

通过build标签配置当前工程的构建过程中的特殊设置,cargo插件。

spring boot入门

spring简介

简化spring开发流程,J2EE开发的一站式解决方案。

优点

  • 快速创建独立运行spring项目以及与主流框架集成
  • 使用嵌入式servlet容器,应用无需达成war包
  • starters自动依赖与版本控制
  • 大量的自动配置,简化开发,也可以修改默认值
  • 无需配置XML,无代码生成
  • 准生产环境的运行时应用监控
  • 与云计算天然集成

微服务

是一种架构风格,其认为一个应用应该是一组小型服务,可以用过HTTP的方式通信。

每一个功能元素最终都是一个可独立替换和独立升级的软件单元。

环境配置

spring-boot-starter

启动器,spring-boot官方提供了一系列启动器。将所有的功能场景抽取出来,只要在项目里面引入这些starter,相关依赖就会自动导入。

主程序类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* @SpringBootApplication标注这是spring boot应用
*/
@SpringBootApplication
public class HelloWorldMainApplication {

public static void main(String[] args){
//spring应用启动
SpringApplication.run(HelloWorldMainApplication.class, args);
}
}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration//表示这是一个Spring Boot的配置类
@EnableAutoConfiguration//开启自动配置功能
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication

@SpringBootConfiguration:表示这是一个Spring Boot的配置类;
@Configuration:配置类上,表示配置类也是容器中的一个组件@Component

1
2
@AutoConfigurationPackage//自动配置包
@Import(EnableAutoConfigurationImportSelector.class)

spring-boot的注释没事可以看看。