第六章 spring boot
1.springboot介绍
springboot是Pivotal公司在2014年推出的全新框架(
不是全新的mvc框架
),它的设计目的是用来快速创建spring应用程序,简化spring应用的开发过程;
spring boot的特点
- 可以创建spring单体应用
- 内置了Servlet容器tomcat、jetty和Undertow(不需要部署war包)
- 提供了starter依赖,简化构建配置
- 可以自动配置spring和第三方框架
- 提供了生产级的功能,如监控、健康检查、和一些外部化配置
- 没有代码生成,不需要xml配置
**总结:**springboot简化了spring应用的开发过程,它不是一个全新的
MVC框架
,默认配置了spring和第三方框架,内置了Servlet容器,可以让我们使用少量代码快速搭建spring应用程序;
2.开发spring boot入门程序
- 软件要求
- JDK1.8+
- Maven3.2+ / Gradle 4+
- Eclipse /STS (Spring Tool Suite) / IDEA
- 内置TOmcat启动日志
默认的ContextPath是
‘’
,即是空的,直接使用localhost:8080/[controller]就可以了
Tomcat started on port(s): 8080 (http) with context path ''
- 修改默认Servlet容器为Jetty
- 排除Tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- 排除内置tomcat -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
- 添加jetty依赖
<!-- 引入Jetty starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
jetty启动日志如下
Jetty started on port(s) 8000 (http/1.1) with context path '/boot'
- 修改默认端口号和默认的ContextOath
springboot启动时自动加载classpath根路径下的application.properties(application.yml)文件,只需要在这个文件中修改端口号和contextPath即可;
## 修改端口号和ContextPath
server.port=8000
server.servlet.context-path=/boot
server:
port: 8000
servlet:
context-path: /boot
2.1 开发流程
- 引入父工程依赖
引入父工程springboot,跟maven聚合工程一样,在springboot中管理了很多所需要的maven依赖,在自己创建的maven工程只需要引入自己所需要的依赖即可,也不需要书写maven的jar包版本号
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
- 书写控制器
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(required = false,defaultValue = "World") String name){
return "Hello" + name;
}
}
- 书写主入口
运行此入口类即可自动开启servlet容器,
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
/**
* 启动自动配置
* 可以使用@SpringBootApplication代替这两个注解
*/
@EnableAutoConfiguration
@ComponentScan(basePackages = "com.etoak")
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class,args);
}
}
- 配置文件
必须在classpath,名称必须是application.properties或者是application.yml
## 修改端口号 和 ContextPath
server.port=8000
server.servlet.context-path=/boot
- 访问页面
localhost:8000/hello
localhost:8000/hello?name=Test
3. boot对静态资源处理
3.1 springmvc对静态资源的处理
- springmvc将静态资源交给servlet容器处理
<mvc:default-servlet-handler />
-
spring mvc定制静态资源的位置和请求地址-xml配置
- 默认访问
src/main/webapp
<mvc:resources location="/static/" mapping="/static/**" />
- 将资源定位到classpath
<mvc:resources location="classpath:/static/" mapping="/**" />
- 将资源位置定制到本地文件系统
<mvc:resources location="file:d:/upload/" mapping="/pic/**" />
- javaconfig方式的springmvc定制静态资源的位置[重要!!!!]⚠️
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class MvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/pic/**") .addResourceLocations("file:d:/upload/"); } }
- 默认访问
3.2 boot的默认方式-静态资源存放位置
- springboot处理方式
在WebMvcAutoConfiguration
中进行了自动配置 WebMvcConfiguration的第484行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VJdDLvJN-1602494043641)(https://ae04.alicdn.com/kf/H5e95135e5b1d415aa049f743bc2e0988C.png)]
- 默认请求地址
/**
- 默认访问位置[访问顺序也如下所示]
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
- 默认路径的访问优先级
classpath:/META-INF/resources/ 最高
classpath:/resources/, 第二
classpath:/static/, 第三
classpath:/public/ 第四
- 修改默认访问地址**[不推荐修改]**
# 在application.properties中修改
spring.mvc.static-path-pattern=/static/**
- 修改默认的访问位置**[不推荐修改]**
# 在application.properties中修改
spring.resources.static-locations=classpath:/static/
- springboot 在默认的基础上增加静态资源访问地址和位置
实现 WebMvcConfiguration
接口中的 addResourceHandlers()
方法
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pic/**")
.addResourceLocations("file:d:/upload/");
}
}
- 当你确定你没有写错文件的路径的时候,可以看一下maven生成的target目录下是不是有你写的static目录,如果没有的话,可以先执行clear命令在执行compile命令
4. boot整合thymeleaf
4.1回顾springmvc整合thymeleaf
- 引入两个maven依赖
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
- 配置三个Bean
<bean id="templateResolver"
class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 页面放置位置 -->
<property name="prefix" value="/templates/" />
<!-- 文件后缀 -->
<property name="suffix" value=".html" />
<!-- 页面编码 -->
<property name="characterEncoding" value="UTF-8" />
<property name="templateMode" value="HTML"/>
<!-- 开发环境不进行缓存,方便调试 -->
<property name="cacheable" value="false" />
</bean>
<!-- 用来解析语法的 -->
<bean id="templateEngine"
class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver"></property>
</bean>
<!-- 渲染页面的 -->
<bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine"></property>
<property name="characterEncoding" value="UTF-8" />
</bean>
4.2boot整合thymeleaf
- 引入spring官方提供的starter依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
- 自动配置thymeleaf
spring官方自动配置Thymeleaf,应该至少将4.1中的三个Bean配置完成;springboot自动整合Thymeleaf在ThymeleafAutoConfiguration类中进行;
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(
{ThymeleafProperties.class})
@ConditionalOnClass({TemplateMode.class, SpringTemplateEngine.class})
@AutoConfigureAfter({WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class})
public class ThymeleafAutoConfiguration {
}
- 自动配置thymeleaf的默认值
- 页面位置:classpath:/templates/
- 页面后缀:.html
- templateMode:HTML
- characterEncoding:UTF-8
- cacheable:true
5. yaml格式配置文件
-
名词解析:YAML(Yet Another Markup Language)
-
YAML语法要求:
- 大小写敏感;
- 使用缩进表示层级关系;
- 缩进时
不允许使用Tab键,只允许使用空格
; - 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可;
-
YAML的优点
- YAML是一个类似 XML、JSON 的标记性语言,YAML 强调以数据为中心;
- 容易阅读;
- 可用于不同程序间的数据交换;
- 适合描述程序所使用的数据结构,特别是脚本语言;
- 丰富的表达能力与可扩展性;
- 易于使用;
范例
server: port: 8001 servlet: context-path: /boot ## 数据源 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1/et1912?serverTimezone=UTC username: root password: dream hikari: maximum-pool-size: 50 thymeleaf: cache: false ## mybatis mybatis: mapper-locations: classpath:/mappers/*.xml type-aliases-package: com.etoak.bean ## 分页插件 pagehelper: reasonable: true ## SQL打印 logging: level: com.etoak.mapper: DEBUG
6. spring整合默认数据源
- springboot2.0之前的数据源是tomcat-jdbc
org.apache.tomcat.jdbc.pool.DataSource
- springboot2.0之后将默认数据源改成了
HikariCP
6.1 JDBC - API
JDK在java.sql包中定义了JDBC的api
Driver
DriverManager
ResultSet
Statement
PreparedStatement
Connection
...
但是java.sql是没有DataSource类型,这个类型在javax.sql中
数据源作用:
- 封装连接数据库的参数(driver、url、username、password)
- 可以使用数据库连接池,节省创建数据库连接的开销,提高效率
数据连接池有哪些
- c3p0、DBCP、tomcat-jdbc、Druid、HikariCP
6.2 boot整合默认数据源的starter依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
6.3 boot数据源相关默认配置
- 数据源通用配置:spring.datasource.*=
- 数据库连接池配置:spring.datasource.连接池名.*=
- 修改默认数据库连接池类型:spring.datasource.type=DruidDataSource
6.4 整合数据源的小问题
6.4.1 驱动过时问题
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'.
引发原因:因为使用高版本的mysql驱动jar包导致
解决办法:使用新的驱动类
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
6.4.2 时区错误
java.sql.SQLException: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone.You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
出现原因:mysql默认时区问题
解决方式:在数据库url连接上加上服务器时区参数
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/et1912?serverTimezone=UTC
6.5 Boot整合Mybatis
springBoot官方并没有自动整合Mybatis,整合工作是有MyBatis官方做的,MyBatis官方提供的starter依赖如下
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>myabtis-spring-boot-starter</artifactId>
</dependency>
添加完成相关的依赖之后,在配置文件中书写配置项
mybatis:
mapper-locations: classpath:/mappers/*.xml
type-aliases-package: com.etoak.bean
在boot项目上开启mapper扫描
@SpringBootApplication
//这里写自己的mapper类存放的路径
@MapperScan(basePackage="com.etoak.mapper")
public class TestApp(){
public static void main(String[] args){
SpringApplication.run(TestApp.class,args);
}
}
错误集锦
- 开启后提示不能创建 bean,应用启动失败
引发原因:可能是给包起别名的地放配置错误
解决办法:详细查看mybatis.type-aliases=package是不是配置到了javabean下
- 提示mapper不是能被注入,
引发原因:Mapper全部都是接口,当错把Mapper接口写成类的时候,会提示不能创建Mapper
解决办法:查看mapper下的Mapper是不是否是接口
6.6 SpringBoot整合PageHelper
springBoot官方并没有自动整合PageHelper,整合工作是有PageHelper官方做的,PageHelper官方提供的starter依赖如下
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
配置相关配置项
pagehelper:
reasonable: true
7. 创建springboot工程
- 配置pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.etoak.et1912.boot</groupId>
<artifactId>boot-02</artifactId>
<version>1.0-SNAPSHOT</version>
<!--整合thymeleaf + 默认数据源hikariCP + mybatis + pagehelper-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependencies>
<!--整合spring mvc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--整合thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--spring-boot-starter-jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 配置application.yml文件
server:
port: 8001
servlet:
context-path: /boot
## 数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1/et1912?serverTimezone=UTC
username: root
password: dream
hikari:
maximum-pool-size: 50
thymeleaf:
cache: false
## mybatis
mybatis:
mapper-locations: classpath:/mappers/*.xml
type-aliases-package: com.etoak.bean
## 分页插件
pagehelper:
reasonable: true
## SQL打印
logging:
level:
com.etoak.mapper: DEBUG
- 在resources下创建相关目录
- 书写控制器等控制单元
- 在顶层包下创建启动类
@SpringBootApplication
@MapperScan(basePackage="com.etoak.mapper")
public class AppMain(){
public static void main(String[] args){
SpringApplication.run(AppMain.class,args);
}
}
8. springboot整合Druid
8.1 创建工程
- 创建maven父工程 boot-druid 并引入相关依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<!-- spring-boot-dependencies pom -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.13</version>
</dependency>
<!-- 以下用于第二种整合方式:手动整合Druid、mybatis、pagehelper -->
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<!-- pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--druid-spring-boot-starter-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
</dependencies>
</dependencyManagement>
- 创建子模块用来存放javabean
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
import lombok.Data;
@Data
public class Car {
private Integer id;
private String brand;
private String series;
private Double price;
private String licensingDate;
private String level;
private String gearbox;
private String outputVolume;
private Double mileage;
private String location;
private String pic;
private String summary;
private String createTime;
}
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor // 无参构造方法
@AllArgsConstructor // 按照所有参数定义顺序生成构造方法
public class Page<T> {
// 页码
private int pageNum;
// 每页显示记录数
private int pageSize;
// 总页数
private int pageCount;
// 总记录数
private long total;
// 数据
private List<T> rows;
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 用于封装结果集
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResultVo {
private static final int SUCCESS_CODE = 200;
private static final String SUCCESS_MESSAGE = "success";
private static final int FAILED_CODE = 201;
private static final String FAILED_MESSAGE = "error";
private int code;
private String message;
private Object data;
public static ResultVo success(Object data) {
return new ResultVo(SUCCESS_CODE, SUCCESS_MESSAGE, data);
}
public static ResultVo failed(Object data) {
return new ResultVo(FAILED_CODE, FAILED_MESSAGE, data);
}
}
- 创建子模块boot-druid-mapper存放mapper
<dependencies>
<!--依赖bean工程-->
<dependency>
<artifactId>boot-druid-bean</artifactId>
<groupId>com.etoak.et1912</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<!--mybatis-spring-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
</dependencies>
package com.etoak.mapper;
import com.etoak.bean.Car;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface CarMapper {
List<Car> queryList(@Param("brand") String brand);
}
在resources下创建mappers目录存放xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.etoak.mapper.CarMapper">
<select id="queryList" parameterType="String" resultType="Car">
SELECT
id,brand,series,licensing_date as licensingDate,
level ,gearbox,output_volume as outputVolume,price,mileage,location,
pic ,create_time as createTime
FROM t_springmvc_car
WHERE 1 = 1
<if test="brand != null and brand != '' ">
AND brand = #{brand}
</if>
ORDER BY create_time DESC
</select>
</mapper>
8.2 第一种整合方式
- 创建子模块boot-druid-01
- 引入相关依赖
mybatis-spring-boot-starter中包含了mybatis 和 mybatis-spring这两个jar包,所以在引入mapper工程的时候需要将这两个jar排除掉,防止依赖冲突
<dependencies>
<!--mapper-->
<dependency>
<artifactId>boot-durid-mapper</artifactId>
<groupId>com.etoak.et1912</groupId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--spring-boot-starter-web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring-boot-starter-jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-spring-boot-starter-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
- 创建springboot配置文件**application.yml**
springboot的可以使用properties或者是yaml格式作为配置文件
示例两种文件进行转换
server.port=8002 server.servlet.context-path=/druid02
server:
port: 8002
servlet:
context-path: /druid01
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/et1912?serverTimezone=UTC
username: root
password: dream
thymeleaf:
cache: false
mybatis:
type-aliases-package: com.etoak.bean
mapper-locations: classpath:/mappers/*.xml
pagehelper:
reasonable: true
- 创建service
import com.etoak.bean.Car;
import com.etoak.bean.Page;
public interface CarService {
Page<Car> queryList(
int pageNum,
int pageSize,
String brand
);
}
//实现类
import com.etoak.bean.Car;
import com.etoak.bean.Page;
import com.etoak.mapper.CarMapper;
import com.etoak.service.CarService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CarServiceImpl implements CarService {
@Autowired
CarMapper carMapper;
@Override
public Page<Car> queryList(int pageNum, int pageSize, String brand) {
// 1.设置分页
PageHelper.startPage(pageNum, pageSize);
// 2.查询
List<Car> carList = carMapper.queryList(brand);
// 3.创建pageInfo
PageInfo<Car> pageInfo = new PageInfo<>(carList);
return new Page<Car>(pageInfo.getPageNum(),
pageInfo.getPageSize(),
pageInfo.getPages(),
pageInfo.getTotal(),
carList);
}
}
- 创建controller
- 创建程序主入口
import com.etoak.bean.Car;
import com.etoak.bean.Page;
import com.etoak.bean.ResultVo;
import com.etoak.service.CarService;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
@MapperScan(basePackages = "com.etoak.mapper")
public class Druid01App {
public static void main(String[] args) {
SpringApplication.run(Druid01App.class,args);
}
@Autowired
CarService carService;
@GetMapping("/car/list")
public ResultVo queryList(
@RequestParam(required = false,defaultValue = "1") int pageNum,
@RequestParam(required = false,defaultValue = "8") int pageSize,
String brand, Model model){
Page<Car> carList = carService.queryList(pageNum, pageSize, brand);
model.addAttribute("carList",carList);
return ResultVo.success(carList);
}
}
8.3 第二种整合方式
此方法较为重要,当第三方jar包没有提供与spring-boo整合的starter时,就需要用java config的方式进行手动整合
- 引入相关依赖
<dependencies>
<!--mapper工程(包含mybatis和mybatis-spring)-->
<dependency>
<artifactId>boot-durid-mapper</artifactId>
<groupId>com.etoak.et1912</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--spring-boot-starter-jdbc-->
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<!--spring mvc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--下边为手动整合的-->
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
</dependency>
</dependencies>
- springboot 配置文件
server:
port: 8003
servlet:
context-path: /druid02
## 自定义
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/et1912?serverTimezone=UTC
username: root
password: dream
filters: wall,stat
## 自定义
mybatis:
mapper-locations: classpath:/mappers/*.xml
type-aliases-package: com.etoak.bean
- 创建javaConfig
后边的是创建druid的监视器,在浏览器输入contextpath/druid 根据配置的账号密码就能实时的查看
@Configuration
@MapperScan(basePackages = "com.etoak.mapper")
@EnableTransactionManagement //注解事务
public class DruidConfig {
/**
* 数据源
* SqlSessionFactoryBean
* @MapperScan
* 4.事务管理器
* 5.开启注解事务
*
* 整合Druid控制台
* 1. springboot 注册servlet
* 2. springboot 注册过滤器
*/
/**
* 默认读取application.yml 中druid开头的配置项
* 其中配置项必须是DruidDataSource中的属性名
* @return
*/
@Bean
@ConfigurationProperties(prefix = "druid")
public DataSource dataSource(){
return new DruidDataSource();
}
//@Value可以直接读取配置文件中的配置项
@Value("${mybatis.type-aliases-package}")
private String typeAliasesPackage;
@Value("${mybatis.mapper-locations}")
private String mapperLocations;
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setTypeAliasesPackage(typeAliasesPackage);
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
Resource[] resources = resolver.getResources(this.mapperLocations);
factoryBean.setMapperLocations(resources);
} catch (IOException e) {
e.printStackTrace();
}
PageInterceptor interceptor = new PageInterceptor();
Properties props = new Properties();
props.setProperty("reasonable","true");
interceptor.setProperties(props);
factoryBean.setPlugins(new Interceptor[] {interceptor});
return factoryBean;
}
@Bean
public DataSourceTransactionManager transactionManager(){
return new DataSourceTransactionManager(this.dataSource());
}
@Bean
public ServletRegistrationBean<StatViewServlet> statViewServlet(){
ServletRegistrationBean<StatViewServlet> statViewServlet = new ServletRegistrationBean<>();
statViewServlet.setServlet(new StatViewServlet());
statViewServlet.addInitParameter("loginUsername","et1912");
statViewServlet.addInitParameter("loginPassword","et1912");
statViewServlet.addInitParameter("allow","127.0.0.1");
statViewServlet.addInitParameter("deny","192.168.5.1/24");
statViewServlet.addUrlMappings("/druid/*");
return statViewServlet;
}
@Bean
public FilterRegistrationBean<WebStatFilter> webStatFilter(){
FilterRegistrationBean<WebStatFilter> webStatFilter = new FilterRegistrationBean<>();
webStatFilter.setFilter(new WebStatFilter());
webStatFilter.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
webStatFilter.addInitParameter("profileEnable","true");
webStatFilter.addUrlPatterns("/*");
return webStatFilter;
}
}
- 第二种javaConfig
package com.etoak.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;
/**
* 1、数据源
* 2、SqlSessionFactoryBean
* 3、@MapperScan
* 4、事务管理器
* 5、开启注解事务
*
* 整合Druid控制台
* 1. springboot注册Servlet
* 2. springboot注册过滤器
*/
@Configuration
@MapperScan(basePackages = "com.etoak.mapper")
@EnableTransactionManagement // 注解事务
public class DruidConfig2 {
@Autowired
DruidProperties props;
@Bean
public DataSource dataSource() {
System.out.println("DruidConfig2");
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(this.props.getDriverClassName());
dataSource.setUrl(this.props.getUrl());
dataSource.setUsername(this.props.getUsername());
dataSource.setPassword(this.props.getPassword());
try {
dataSource.setFilters(this.props.getFilters());
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return dataSource;
}
// @Value可以直接读取application.yml文件中的配置项
@Value("${mybatis.type-aliases-package}")
private String typeAliasesPackage;
@Value("${mybatis.mapper-locations}")
private String mapperLocations;
@Bean
public SqlSessionFactoryBean sqlSession(DataSource dataSource) {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setTypeAliasesPackage(this.typeAliasesPackage);
/* mapperLocations属性 */
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
Resource[] resources = resolver.getResources(this.mapperLocations);
factory.setMapperLocations(resources);
} catch (IOException e) {
e.printStackTrace();
}
/* 分页插件 */
PageInterceptor interceptor = new PageInterceptor();
Properties props = new Properties();
props.setProperty("reasonable", "true");
interceptor.setProperties(props);
factory.setPlugins(new Interceptor[] { interceptor });
return factory;
}
@Bean
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(this.dataSource());
}
@Bean
public ServletRegistrationBean<StatViewServlet> statViewServlet() {
ServletRegistrationBean<StatViewServlet> statViewServlet = new
ServletRegistrationBean<>();
// <servlet-class></servlet-class>
statViewServlet.setServlet(new StatViewServlet());
// init-param(登录名、登录密码、允许访问控制台的ip和拒绝访问控制台的ip)
statViewServlet.addInitParameter("loginUsername", "et1912");
statViewServlet.addInitParameter("loginPassword", "et1912");
statViewServlet.addInitParameter("allow", "127.0.0.1");
statViewServlet.addInitParameter("deny", "192.168.5.1/24");
// url-pattern
statViewServlet.addUrlMappings("/druid/*");
return statViewServlet;
/*
* <servlet>
* <servlet-name></servlet-name>
* <servlet-class></servlet-class>
* <init-param>
</init-param>
* </servlet>
* <servlet-mapping>
* <servlet-name></servlet-name>
* <url-pattern></url-pattern>
* </servlet-mapping>
*/
}
@Bean
public FilterRegistrationBean<WebStatFilter> webStatFilter() {
FilterRegistrationBean<WebStatFilter> webStatFilter = new
FilterRegistrationBean<>();
// filter-class
webStatFilter.setFilter(new WebStatFilter());
// init-param
webStatFilter.addInitParameter("exclusions",
"*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
webStatFilter.addInitParameter("profileEnable",
"true");
// url-pattern
webStatFilter.addUrlPatterns("/*");
return webStatFilter;
}
}
- 创建与4配套的配置类
package com.etoak.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "druid")
@Component
@Data
public class DruidProperties {
private String driverClassName;
private String url;
private String username;
private String password;
private String filters;
}
8.4 第三种整合方式
使用druid官方提供的springboo的starter依赖
- maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
- 配置相关的配置文件
server:
port: 8000
servlet:
context-path: /druid03
## 配置数据源
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/database?serverTimezone=UTC
username:
password:
druid:
## 初始化连接数
initial-size: 50
##最大活跃数
max-active: 50
##验证空闲的连接
validation-query: select 1
filter: wall,stat
##开启druid监视器,注册servlet和filter
stat-view-serlvet:
enabled: true
login-username: root
login-password: root
## 白名单,允许该IP访问多个访问地址由逗号隔开
allow: 127.0.0.1
## 黑名单:不允许192.168.5.1下的所有端口访问
## deny的规则高于allow,若果两个配置下有同一个ip,也不能访问
deny: 192.168.5.1/24
##是否开启重置,开启后可以使热面重置,计数器清空
reset-enable: true
url-pattern: "/druid/*"
web-stat-filter:
enable: true
## 启用配置文件配置,可以看到每个url调用的SQL语句
profile-enable: true
## 排除特定的访问路径
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
url-pattern: "/*"
## 在控制台打印SQL
logging:
level:
com.etoak.mapper: DEBUG
8.5 启动druid的监视器
在配置完成之后,可以通过 context-path/druid ,输入账号密码访问
9.springboot 整合dubbo
- 引入相关的依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependencies>
<!-- spring-boot-dependencies pom -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- dubbo-spring-boot-starter -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<!-- mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<!-- pagehelper-spring-boot-starter -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.13</version>
</dependency>
</dependencies>
- 需要用到的bean
public class User{
private Integer id;
private String name;
private Integer age;
}
9.1创建 dubbo 接口
- 创建接口
package com.example.service;
//dubbo服务
public interface UserService{
User getById(int id);
}
- 创建本地存根
需要在接口的同级包下创建本地存根方法实现接口方法
package com.example.service;
public class UserServiceStub implements UserService {
private UserService userService;
public UserServiceStub(UserService userService) {
this.userService = userService;
}
@Override
public User getById(int id) {
if(id <= 0 ) {
System.out.println("参数异常");
return new User();
}
return userService.getById(id);
}
}
9.2 创建Dubbo服务提供者
- 创建mapper接口
import com.etoak.bean.User;
public interface UserMapper {
User getById(int id);
}
- 创建数据库映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.etoak.mapper.UserMapper">
<select id="getById" parameterType="int" resultType="User">
SELECT id,
name,
age
FROM t_springmvc_user
WHERE id = #{value}
</select>
</mapper>
- 创建service [此处继承的是 interface 工程下的 UserService]
import com.alibaba.dubbo.config.annotation.Service;
import com.etoak.bean.User;
import com.etoak.mapper.UserMapper;
import com.etoak.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@Service(stub = "com.etoak.service.UserServiceStub") // 这个@Service是dubbo提供的
@Slf4j
public class UserServiceImpl implements UserService {
@Autowired
UserMapper userMapper;
@Override
public User getById(int id) {
log.info("param id - {}", id);
User user = userMapper.getById(id);
log.info("user - {}", user);
return user;
}
- 对外暴露服务[application.yml]
server:
port: 9001
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/et1912?serverTimezone=UTC
username: root
password: root
mybatis:
type-aliases-package: com.etoak.bean
mapper-locations: classpath:/mappers/*.xml
pagehelper:
reasonable: true
logging:
level:
com.etoak.mapper: debug
## Dubbo配置
dubbo:
application:
name: user-service
registry:
address: zookeeper://127.0.0.1:2181
protocol:
name: dubbo
port: 20880
- 创建启动类
@SpringBootApplication
@EnableDubbo //开启Dubbo自动配置
@MapperScan(basePackages="com.etoak.mapper")
public class Main{
public static void main(String[] args){
SpringApplication.run(Main.class,args);
}
}
9.3 创建服务的消费者
- 创建配置文件 [application.yml]
server:
port: 8080
dubbo:
application:
name: user-consumer
registry:
address: zookeeper://127.0.0.1:2181
- 创建启动类消费消息
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import com.etoak.bean.User;
import com.etoak.service.UserService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@EnableDubbo
@RestController
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
@Reference(check = false, timeout = 3000) // dubbo提供的 用于订阅dubbo服务
UserService userService;
@GetMapping("/user/{id}")
public User getById(@PathVariable int id){
return userService.getById(id);
}
}
10.springboot整合swagger2
spring基于swagger规范,可以将SpringMVC和SpringBoot 项目代码,自动生成JSON格式的描述文件,本省不是Swagger官网提供的
1. 引入maven依赖
<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>
2. 创建工程
- 创建使用的javabean
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String name;
private Integer age;
}
- 创建config
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket doc() {
ApiInfo apiInfo = new ApiInfoBuilder()
.title("Rest风格的api文档")
.description("这是描述信息")
.termsOfServiceUrl("http://www.etoak.com")
.license("某某许可证")
.build();
Docket doc = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo)//
.select()
.paths(PathSelectors.any())
.apis(RequestHandlerSelectors
.basePackage("com.etoak.controller")
).build();
return doc;
}
- 创建controller
import com.etoak.bean.User;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/user")
@Api(tags = "用户服务接口")
public class UserController {
@GetMapping("/query")
@ApiOperation(value = "查询用户",
notes = "<font size='6' color='red'><b>查询用户</b></font>")
@ApiImplicitParams({
@ApiImplicitParam(name="name", value = "用户名",
required = false, paramType = "query"),
@ApiImplicitParam(name="id", value = "用户id",
required = false, paramType = "query")
})
@ApiResponses({
@ApiResponse(code = 200, message = "成功"),
@ApiResponse(code = 401, message = "没有权限访问"),
@ApiResponse(code = 403, message = "拒绝访问"),
@ApiResponse(code = 404, message = "不存在"),
})
public User query(String name,
@RequestParam(required = false, defaultValue = "0") int id) {
return new User(id, name, 22);
}
@ApiImplicitParam(name="id", value = "用户id",
required = true, paramType = "path")
@ApiOperation(value = "根据id查询用户", notes = "根据id查询用户")
@GetMapping("/{id}")
public User query(@PathVariable int id) {
return new User(id, "et1912", 20);
}
@PostMapping("/add")
public String add(@RequestBody User user) {
System.out.println("user - " + user);
return "success";
}
}
- 创建启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BootSwaggerApp {
public static void main(String[] args) {
SpringApplication.run(BootSwaggerApp.class, args);
}
}
3. 杂七杂八
- 访问地址
http://ip:port/contextPath/swagger-ui.html
- 常用注解
@Api 用在类上,为她创建一组api文档
@ApiOperation 用在方法上,对某一个接口进行描述
@ApiImplicitParam 可用于对多个参数描述
@ApiImplicitParam 对单个参数描述
@ApiResponses 描述多个响应信息
@ApiResponse 描述一个响应信息
@ApiModel 对bean描述
@ApiProperty 对bean的属性描述
11.springboot整合quartz
1 quartz的核心api
Job:任务接口,任务类需要实现的接口
JobDetail:用于描述任务
Trigger:定义调度规则
- SimpleTrigger:可以定义任务何时执行、执行多久、何时停止等
- CronTrigger:使用cron表达式定义任务执行规则
Scheduler:任务调度器
JobStore:任务存储
Jobkey、TriggerKey、JonDataMap、JonExecutionContext
2 spring整合单机版的quartz
-
MethodInvokingJobDetailFactoryBean
特点:不要任务类实现任何接口
属性:name、group、targetObject、targetMethod
-
CronTriggerFactoryBean
属性:jobDetail、name、group、cronExpression
-
SchedulerFactoryBean
属性:triggers
3 spring整合集群版quartz
-
数据源
-
事务管理器
-
JobDetailFactoryBean
特点:要求job任务继承QuartzJobBean类
属性:name、group、jobClass(任务类名)、durability
-
CronTriggerFactoryBean
属性:jobDetail、name、group、cronExpression
-
ScheculerFactoryBean
属性:triggers、数据源、事务管理器、集群配置文件、applicationContextScheculerContextKey、jobFactory
4 springboot整合单机版quartz
springboot官方整合了quartz框架;
-
maven依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
-
实现步骤
1、创建任务类
2、配置spring bean
3、测试
5 springboot整合集群版quartz
-
maven依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
-
实现步骤
1. 创建数据库(使用et1912)和表(quartz框架提供) 2. 集群配置文件(quartz.properties放到classpath下) 3. 创建任务,继承QuartzJobBean 4. 配置spring bean 数据源 事务管理器 JobDetailFactoryBean CronTriggerFactoryBean SchedulerFactoryBean
12.springboot调用远程服务
两个工程都需要用到的javabean
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User{
private Integer id;
private String name;
private Integer age;
}
1.创建服务接口
把springboot的项目启动类和控制器整合在了一起,因为没有配置端口号,所以用的是默认的端口8080
package com.etoak;
import com.etoak.bean.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class ServerApp {
public static void main(String[] args) {
SpringApplication.run(ServerApp.class,args);
}
@RequestMapping("/get")
public User test2(String name){
return new User(1,name,20);
}
@RequestMapping("/post_kv")
public User postKv(User user){
user.setId((int)(Math.random()*100));
return user;
}
@PostMapping("/post_json")
public User postJosn(@RequestBody User user){
user.setName("postJson");
return user;
}
}
2. 创建客户端
- 引入maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
- 设置启动端口,不能与服务端的一致
## application.yml
server:
port: 8001
- 创建连接的工具类
package com.etoak.util;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.*;
public class OwnHttpUtil {
private static final Integer SUCCESS_CODE = 200;
private static final Integer NOT_FOUND = 404;
private static final Integer NOT_SUPPORT = 405;
private static final Integer ERROR = 500;
public static String get(String url){
//返回的json字符串
String result = "{}";
//创建HttpClient
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
try {
//执行url
CloseableHttpResponse response = httpClient.execute(httpGet);
//获取状态行
StatusLine statusLine = response.getStatusLine();
//获取状态编码
int code = statusLine.getStatusCode();
if(SUCCESS_CODE == code){
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity);
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static String postKv(String url, Map<String,Object> paramMap){
String result = "{}";
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
//创建集合存放参数
List<NameValuePair> params = new ArrayList<>();
//从map中获取值给params赋值
Set<Map.Entry<String, Object>> entrySet = paramMap.entrySet();
Iterator<Map.Entry<String, Object>> car = entrySet.iterator();
while(car.hasNext()) {
Map.Entry<String, Object> entry = car.next();
params.add(
new BasicNameValuePair(
entry.getKey(),
String.valueOf(entry.getValue())
)
);
}
try {
httpPost.setEntity(new UrlEncodedFormEntity(params));
CloseableHttpResponse response = httpClient.execute(httpPost);
//获取响应行
StatusLine statusLine = response.getStatusLine();
int code = statusLine.getStatusCode();
if(SUCCESS_CODE == code){
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity);
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static String postJson(String url,String json){
String result = "{}";
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
try {
CloseableHttpResponse response = httpClient.execute(httpPost);
if(SUCCESS_CODE == response.getStatusLine().getStatusCode()){
result = EntityUtils.toString(response.getEntity());
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
13. spring 整合springtask
spring task 是spring 3.0之后提供的任务调度器,相比Quartz,使用起来更加的方便
spring task 在spring 框架的 spring-context模块中,boot整合只需要添加 spring-boot-starter-web依赖即可
1. 使用spring task
在启动类上添加 @EnabkeScheduling 注解
创建一个任务,在方法上加上@Scheduled注解即可
import cn.hutool.core.date.DateUtil;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
@SpringBootApplication
@EnableScheduling // 启动springtask配置
public class SpringTaskApp {
public static void main(String[] args) {
SpringApplication.run(SpringTaskApp.class, args);
}
@Scheduled(cron = "0/5 * * * * ?")
public void sendEmail() {
System.out.println(
Thread.currentThread().getName() + " - " +
DateUtil.now() + " - 邮件下发");
}
@Scheduled(cron = "0/5 * * * * ?")
public void sendSms() {
System.out.println(
Thread.currentThread().getName() + " - " +
DateUtil.now() + " - 短信下发");
}
}
X.杂七杂八
- @SpringBootApplication
此注解相当于 @Configuration[标明当前类是一个配置类] 、 @EnableAutoConfiguration[开启自动配置] 、@ComponeScan[注解扫描] 三个注解
- boot 拦截器
创建拦截器
拦截器需要**实现HandlerInterceptor,并且重写preHandler方法,具体的拦截规则书写在此方法体内**
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String uri = request.getRequestURI();
boolean b = request.getRequestURI().contains("/css");
System.out.println("拦截的地址- " + uri);
return b;
}
}
配置
通过java config的方式配置拦截器拦截哪些url
方法 简介 addInterceptor 添加拦截器实现类 addPathPatterns 添加要拦截的请求 /** :表示拦截所有的请求 excludePathPatterns 排除哪些请求
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Autowired
LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/test2/**")
.excludePathPatterns("/user/login/**")
//.excludePathPatterns("/lib/**")
.excludePathPatterns("/user/quit/**");
}
}
- 配置静态view访问路径
package com.etoak.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("/js/**")
.addResourceLocations("/css/**")
.addResourceLocations("classpath:/static/");
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/toInfo").setViewName("info");
registry.addViewController("/toCart").setViewName("cart");
registry.addViewController("/toOrder").setViewName("order");
}
}
静态页面
<ul class="nav navbar-nav">
<li>
<a th:href="@{/toInfo}" target="et1912">商品信息管理</a>
</li>
<li>
<a th:href="@{/toCart}" target="et1912">购物车管理</a>
</li>
<li>
<a th:href="@{/toOrder}" target="et1912">订单管理</a>
</li>
<li>
<a th:href="@{/user/toLogout}">用户退出</a>
</li>
</ul>