文章目录

 

一、前言

新成员加入,SpringBoot之诞生_1024程序员节

金手指:springboot是一个java应用
springboot使用java -jar启动它,就能得到一个生产级别的web工程。
springboot工程是打成一个jar包,不是war包,但是确实是web工程。
springboot是一个jar工程,所以不需要web.xml
applicationContext.xml没有 数据库连接+MapperScan+Mapper.xml application.properties文件代替

金手指1: idea中shift shift 并不能找到任何东西,要使用Edit/Find/Find in Path
金手指2:对于不同的生产环境、测试环境,最好配置多个application.properties,使用spring.profiles.active 区分不同环境下配置文件。
新成员加入,SpringBoot之诞生_1024程序员节_02

二、快速搭建一个springboot应用

2.1 依赖和配置文件

新建一个springboot项目,建立用阿里骨架,导入依赖,这里需要四个依赖,分别是:

springboot启动器、
lombok提供@Data、
mysql-connector-java设置数据库四个、
通用mapper依赖(里面提供了jdbc和mybatis和配置文件中的驼峰,所以这两个依赖不需要了,配置文件中驼峰也不需要了)

2.1.1 依赖

      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.0.3</version>
        </dependency>

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_03

2.1.2 配置文件

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_04

2.2 springboot配置拦截器两板斧

配置拦截器两板斧:定义拦截器、使用拦截器

2.2.1 定义拦截器

新建一个类implements HandlerInterceptor,实现三个方法,打印日志

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_05

2.2.2 使用拦截器

新建配置类(类名任意,用@Configuration注解配置),implements WebMvcConfigurer,实现addInterceptors()方法,添加自定义拦截器并设置路径为全部/** (一定要两个星号)
新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_06

2.3 pojo层

新成员加入,SpringBoot之诞生_1024程序员节_07

@Table注解 通用mapper提供,类与表名对应
@Data注解 lombok包提供,不需要setter-getter和toString
@NoArgsCo’nstructor注解 lombok包提供,不需要无参数构造函数
@AllArgsCo’nstructor注解 lombok包提供,不需要无参数构造函数
@Id 注解 通用mapper提供,标记为主键
@KeySql(useGeneratedKeys=true) 通用mapper提供,标志为自增长
@Transient 表示该属性不是表示表中列

2.4 Mapper层(通用mapper)

新成员加入,SpringBoot之诞生_1024程序员节_08

2.5 Service层

2.5.1 service层

新成员加入,SpringBoot之诞生_1024程序员节_09

金手指:通用mapper的好用、高效、简洁、适当修改
1、好用:不再需要mapper.xml
2、高效:通用mapper内置连接池来缓存,性能高,只要生成一次sql语句
3、简洁(依赖和配置文件):
3.1 没有使用通用mapper,需要三个依赖
mybatis-spring-boot-starter、spring-boot-starter-jdbc 、mysql-connector-java 三个依赖;
使用通用mapper之后,只需要mapper-spring-boot-starter、mysql-connector-java 两个依赖,因为通用mapper依赖中包含mybatis和jdbc依赖,但是没有包含数据库驱动
3.2 没有使用通用mapper,配置文件关于mybatis三个配置
mybatis.type-aliases-package=pojo所在类
mybatis.mapper-locations=XxxMapper.xml路径,
mybatis.configuration.map-underscore-to-camel-case=true
使用通用mapper之后,可以去掉驼峰mybatis.configuration.map-underscore-to-camel-case=true,因为通用mapper内部实现了。
4、适当修改:mapper接口和启动类
public interface UserMapper extends Mapper {
以前启动类中的@MapperScan import org.mybatis.spring.annotation.MapperScan;
使用通用mapper之后,import tk.mybatis.spring.annotation.MapperScan;

2.5.2 使用通用mapper三步走

第一步:依赖和配置文件

导入依赖删除mybatis和jdbc依赖,配置文件去掉驼峰

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>2.0.2</version>
</dependency>

第二步:mapper类与启动类扫描

public interface UserMapper extends Mapper<User> {
}

启动类中@MapperScan 包从org.mybatis变为tk.mybatis

第三步(可选):检查一下pojo,加上必要注解

这里@Id @Table @KeySql(useGeneratedKeys = true) @Transient

2.6 controller

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_10

@RestController @Controller+@ResponseBody 返回结果,返回为json,适应前后端完成分离

@RequestMapping @GetMapping // 类上面用RequestMapping 方法上面用GetMapping,很好

@PathVariable(“id”) url中包含的序号,id为主

金手指:
不是@GetMapping({“id”}) 是@GetMapping("{id}") 笔者写错了,所以一直是404

2.7 运行成功

新成员加入,SpringBoot之诞生_1024程序员节_11

三、需要注意的地方

3.1 application.properties文件

(也可以是application.yaml,笔者喜欢application.yaml)

端口:server.port 默认是8080,默认使用tomcat服务器,可以修改,这里用默认的,可以省略

拦截路径:server.servlet.path=/ 已过时,默认就是拦截所有,不用配置

日志级别:一共六种 TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF,
直接从配置文件中点击去就可以知道,如下:
新成员加入,SpringBoot之诞生_1024程序员节_12
默认是Info,这里配置为debug,显示的更加详细,但是其他速度变慢了
数据库四个配置:application.properties配置数据库四属性
新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_13
mybatis两个配置:mybatis.type-aliases-package pojo所在类
mybatis.mapper-locations 设置Mapper.xml文件,参数为String数组,可设置多个

新成员加入,SpringBoot之诞生_1024程序员节_14

金手指:
1、application.yaml文件,key与key之间一般空格左偏移两行 key与value之间一定有空格
2、如果同时配置application.properties 和 application.yaml,运行时取并集,若冲突,取properties文件中的
3、application.yaml文件,包括配置自定义对象user 配置集合language
新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_15

3.2 Mapper接口

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_16

3.3 启动类

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_17

3.4 静态资源存放目录

四个静态资源地址,看源码
上面代码使用resources/static目录存放静态资源,实际上不仅仅这一个地方

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_18

新成员加入,SpringBoot之诞生_1024程序员节_19

实践开发中,完全前后端分离,前端形成独立的工程,如vue等,不需要将前端导入到后端,所以这个静态资源存放的目录没什么用。

金手指:
ctrl+shift+U 变量中各个字符变为大写
ctrl+alt+B 找到接口的实现Implement 阅读源码和别人代码的方式

3.5 maven

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_20

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_21

金手指:dependencies和dependencyManagement区别
dependencyManagement:dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显式的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。即dependencyManagement只是提供版本而不是依赖,如果子项目中声明版本,会覆盖dependencyManagement提供的版本。
dependencies:子项目会继承父项目dependencies中的依赖,dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)
小结:dependencies中的jar直接加到子项目中,管理的是依赖关系(如果有父pom,子pom,则子pom中只能被动接受父类的版本);dependencyManagement主要管理版本,对于子类继承同一个父类是很有用的,集中管理依赖版本不添加依赖关系,对于其中定义的版本,子pom不一定要继承父pom所定义的版本,可以自己显示指定。
实践开发实践开发中,父项目是一个maven空工程,pom.xml打包方式packaging为pom,提供统一的包版本管理,然后在里面新建各个module为子项目,开始具体逻辑。在我们项目顶层的POM文件中,我们会看到dependencyManagement元素。通过它元素来管理jar包的版本,让子项目中引用一个依赖而不用显示的列出版本号。Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用在这个dependencyManagement元素中指定的版本号。

3.5.1 maven右边plugins爆红

一般是网络问题

就像下图所示,我是刚创建的spring boot 项目,就给我报错了,啥配置都没改,也都对,还是报这个错误。

新成员加入,SpringBoot之诞生_1024程序员节_22
然后根据它报的错误找 [Lifecycle] 里对应的功能,右键 Run Maven Build ,

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_23

然后再 [Reimport] 一下,然后我问题就解决了。 希望可以帮到你们。

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_24

3.5.2 maven右边Dependency爆红

一般是网络问题

3.5.2.1 方案一:修改pom 配置文件

修改pom 配置文件,将标红的依赖先删除,并点击reimport, 之后重新加上出错的依赖,再reimport

修改pom 配置文件,讲标红的依赖先删除,并点击reimport, 之后重新加上出错的依赖,再reimport

删除前

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_25

删除后

新成员加入,SpringBoot之诞生_1024程序员节_26
重新添加冲突的依赖 并 remport

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_27

3.5.2.2 方案二:从删除本地仓库中的文件目录

从删除本地仓库中的文件目录,强制 maven 重新下载该包

从删除本地仓库中的文件目录,强制 maven 重新下载该包

1.找到本地的包并删除

新成员加入,SpringBoot之诞生_1024程序员节_28

2.让maven 重新下载对应的包

新成员加入,SpringBoot之诞生_1024程序员节_29

右边有了,处理好了

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_30

3.5.2.3 终极方案,比方案一多了一个mvn clean

首先,清理pom中的依赖的jar,并强制重新下载相关依赖

mvn dependency:purge-local-repository

再将标红的pom文件增加注释

新成员加入,SpringBoot之诞生_1024程序员节_31

执行指令

mvn clean

去除依赖注释

新成员加入,SpringBoot之诞生_1024程序员节_32

执行reimport,右边有了,处理好了
新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_33

3.5.3 idea修改所有项目的配置,idea修改默认maven配置

File/Other Settings/Default Settings

3.6 args参数

金手指:main函数中args参数有什么用?
只有在idea终端Terminate才有用
新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_34

3.7 springboot的一些注解

Springboot管理数据库的四个key

@Configuration 标注在类上,声明一个类作为配置类,代码配置文件xml文件
@Bean 标注在方法上,将方法返回值加入Bean容器,代替标签
@Value 标注在属性上,属性注入
@PropertySource 指定外部属性文件

@Data注解 编译时生成 getter-setter 必要的构造函数
@ConfigurationProperties @EnableConfigurationProperties

3.8 server.context-path 和 spring.mvc.servlet.path

server.context-path 和 server.servlet.path 是完全不同的两个东西

1、server.context-path设定应用的context-path.
2、server.servlet.path设定dispatcher servlet的监听路径,默认为: /

3.8.1 server.context-path

server.context-path或 server.servlet.context-path都是一样的,都是在ServerProperties.java里面,好像是spring-boot版本的问题

定义: server.context-path= # Context path of the application. 应用的上下文路径,也可以称为项目路径,是构成url地址的一部分。
在每个module的application.properties文件都可以配置server.context-path这个属性 开始使用spring boot的时候没有注意这个属性,其实默认可以不配置,直接在controller层通过@RequestMapping来设定url的地址路径。如下:

@RestController 
@RequestMapping("/mqcp") 
public class MQCPContorller {
    @Autowired
    MQCPServiceImpl mqcpService;
    @RequestMapping("/convert")
    public String convert(){
        mqcpService.convert();
        return "ok";
    } } 

如果server.context-path没有配,请求的url地址就是 localhost : port/mqcp/convert 如果server.context-path = “/market/task”, 请求的url地址就是 localhost : port/market/task/mqcp/convert 在 task这个模块下的所有web层的url地址都需要添加server.context-path。

server.context-path 在ngnix分发中的作用

ngnix 分发的时候 server.context-path 起到了很重要的作用,并且如果server.context-path 值没有写规范也会导致挖出一个巨大的坑。 下面是ngnix的部分配置文件

upstream task{
    server 100.100.88.152:8097;
    check interval=30000 rise=2 fall=3 timeout=1000 type=http;
    check_http_send "GET /market/task/turnTask  HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx; } server {
    location /market/task/ {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://task;
    } } 

实现的功能是所有的请求中如果url中包含/market/task/的请求,都被分发到server
100.100.88.152:8097,这个ip和端口的服务器上。 很明显,如果task模块配置了server.context-path= /market/task 那么task模块下的所有web接口url地址都必须加上 /market/task, 那么在task模块下的web层所有接口都可以分发到server
100.100.88.152:8097上,不用考虑新增的Controller类上的路径和接口上定义的路径。

反之,如果没有配置server.context-path,或者server.context-path配置的没有区别性,比方说配置为/market ,无法和其他模块区分开来,那么ngnix就没有办法分发出去。这样模块下web层每次新增一个Controller类,为了能够让ngnix正常分发,不报404错误,需要在ngnix上对类的url地址进行配置,这是一件很麻烦的事情。所以server.context-path的规范配置很关键。

实际开发中,如果spring-boot配置文件中server.context-path=/XXXXXXX不起作用: 原因是更新后写法变成了server.servlet.context-path=/XXXXXX,这样写即可

3.8.2 spring.mvc.servlet.path

从server.servlet.path到spring.mvc.servlet.path

server.servlet.path 被弃用,现在用spring.mvc.servlet.path,

如何得知?
在application.properties中,使用server.servlet.path 发现已过时,点进去spring-configuration-metadata.json就可以看到

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_35

金手指:不要使用已过时的东西,既然一个东西已过时,那么设计者就有义务提供一个新的代替,开发者一定可以找到这个新的代替的

spring.mvc.servlet.path

新成员加入,SpringBoot之诞生_# (3)SpringBoot框架_36

新成员加入,SpringBoot之诞生_1024程序员节_37

一个是context 全局加上一个前缀
一个是拦截 只有到url中有拦截相同的才放行
总结:url中两个都要有 ip:port/context/拦截/子路径,和springcloudZuul有类似之处

金手指:spring.mvc.servlet.path注意两点
1、其值必须以 / 开头
2、其值必须不可以包含 * ,一定要明确

四、小结

分为两个部分,分别是搭建springboot项目和解释springboot项目。

天天打码,天天进步!!!