文章目录
一、前言
二、快速搭建一个springboot应用金手指: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 区分不同环境下配置文件。
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>
2.1.2 配置文件
2.2 springboot配置拦截器两板斧
配置拦截器两板斧:定义拦截器、使用拦截器
2.2.1 定义拦截器
新建一个类implements HandlerInterceptor,实现三个方法,打印日志
2.2.2 使用拦截器
新建配置类(类名任意,用@Configuration注解配置),implements WebMvcConfigurer,实现addInterceptors()方法,添加自定义拦截器并设置路径为全部/** (一定要两个星号)
2.3 pojo层
@Table注解 通用mapper提供,类与表名对应
@Data注解 lombok包提供,不需要setter-getter和toString
@NoArgsCo’nstructor注解 lombok包提供,不需要无参数构造函数
@AllArgsCo’nstructor注解 lombok包提供,不需要无参数构造函数
@Id 注解 通用mapper提供,标记为主键
@KeySql(useGeneratedKeys=true) 通用mapper提供,标志为自增长
@Transient 表示该属性不是表示表中列
2.4 Mapper层(通用mapper)
2.5 Service层
2.5.1 service层
金手指:通用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
@RestController @Controller+@ResponseBody 返回结果,返回为json,适应前后端完成分离
@RequestMapping @GetMapping // 类上面用RequestMapping 方法上面用GetMapping,很好
@PathVariable(“id”) url中包含的序号,id为主
金手指:
不是@GetMapping({“id”}) 是@GetMapping("{id}") 笔者写错了,所以一直是404
2.7 运行成功
三、需要注意的地方3.1 application.properties文件
(也可以是application.yaml,笔者喜欢application.yaml)
端口:server.port 默认是8080,默认使用tomcat服务器,可以修改,这里用默认的,可以省略
拦截路径:server.servlet.path=/ 已过时,默认就是拦截所有,不用配置
日志级别:一共六种 TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF,
直接从配置文件中点击去就可以知道,如下:
默认是Info,这里配置为debug,显示的更加详细,但是其他速度变慢了
数据库四个配置:application.properties配置数据库四属性
mybatis两个配置:mybatis.type-aliases-package pojo所在类
mybatis.mapper-locations 设置Mapper.xml文件,参数为String数组,可设置多个
金手指:
1、application.yaml文件,key与key之间一般空格左偏移两行 key与value之间一定有空格
2、如果同时配置application.properties 和 application.yaml,运行时取并集,若冲突,取properties文件中的
3、application.yaml文件,包括配置自定义对象user 配置集合language
3.2 Mapper接口
3.3 启动类
3.4 静态资源存放目录
四个静态资源地址,看源码
上面代码使用resources/static目录存放静态资源,实际上不仅仅这一个地方
实践开发中,完全前后端分离,前端形成独立的工程,如vue等,不需要将前端导入到后端,所以这个静态资源存放的目录没什么用。
金手指:
ctrl+shift+U 变量中各个字符变为大写
ctrl+alt+B 找到接口的实现Implement 阅读源码和别人代码的方式
3.5 maven
金手指: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 项目,就给我报错了,啥配置都没改,也都对,还是报这个错误。
然后根据它报的错误找 [Lifecycle] 里对应的功能,右键 Run Maven Build ,
然后再 [Reimport] 一下,然后我问题就解决了。 希望可以帮到你们。
3.5.2 maven右边Dependency爆红
一般是网络问题
3.5.2.1 方案一:修改pom 配置文件
修改pom 配置文件,将标红的依赖先删除,并点击reimport, 之后重新加上出错的依赖,再reimport
修改pom 配置文件,讲标红的依赖先删除,并点击reimport, 之后重新加上出错的依赖,再reimport
删除前
删除后
重新添加冲突的依赖 并 remport
3.5.2.2 方案二:从删除本地仓库中的文件目录
从删除本地仓库中的文件目录,强制 maven 重新下载该包
从删除本地仓库中的文件目录,强制 maven 重新下载该包
1.找到本地的包并删除
2.让maven 重新下载对应的包
右边有了,处理好了
3.5.2.3 终极方案,比方案一多了一个mvn clean
首先,清理pom中的依赖的jar,并强制重新下载相关依赖
mvn dependency:purge-local-repository
再将标红的pom文件增加注释
执行指令
mvn clean
去除依赖注释
执行reimport,右边有了,处理好了
3.5.3 idea修改所有项目的配置,idea修改默认maven配置
File/Other Settings/Default Settings
3.6 args参数
金手指:main函数中args参数有什么用?
只有在idea终端Terminate才有用
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就可以看到
金手指:不要使用已过时的东西,既然一个东西已过时,那么设计者就有义务提供一个新的代替,开发者一定可以找到这个新的代替的
spring.mvc.servlet.path
四、小结一个是context 全局加上一个前缀
一个是拦截 只有到url中有拦截相同的才放行
总结:url中两个都要有 ip:port/context/拦截/子路径,和springcloudZuul有类似之处 。金手指:spring.mvc.servlet.path注意两点
1、其值必须以 / 开头
2、其值必须不可以包含 * ,一定要明确
分为两个部分,分别是搭建springboot项目和解释springboot项目。
天天打码,天天进步!!!