整合篇包含SpringBoot对各种第三方技术的整合。例如SQL、NoSQL、缓存、消息队列、定时任务、文档操作、认证授权、消息通知等等
小简从 0 开始学 Java 知识之 Java-学习路线 中的《SpringBoot-整合篇》,不定期更新所学笔记,期待一年后的蜕变吧!<有同样想法的小伙伴,可以联系我一起交流学习哦!>
步骤①:导入 MyBatis 的 starter 和对应数据库的坐标,或者创建项目时勾选要使用的技术
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
步骤②:配置数据源相关信息,没有这个信息你连接哪个数据库都不知道
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=Asia/Shanghai
username: root
password: root
测试
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for tbl_book
-- ----------------------------
DROP TABLE IF EXISTS `tbl_book`;
CREATE TABLE `tbl_book` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`type` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`description` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tbl_book
-- ----------------------------
INSERT INTO `tbl_book` VALUES (1, '三体', '科幻', '大刘的巅峰之作,将中国科幻推向世界舞台。总共分为三部曲:《地球往事》、《黑暗森林》、《死神永生》。');
INSERT INTO `tbl_book` VALUES (2, '格林童话', '童话', '睡前故事。');
INSERT INTO `tbl_book` VALUES (3, 'Spring 5设计模式', '计算机理论', '深入Spring源码剖析Spring源码中蕴含的10大设计模式');
SET FOREIGN_KEY_CHECKS = 1;
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
@Mapper
public interface BookDao {
@Select("select * from tbl_book where id = #{id}")
public Book getById(Integer id);
}
@SpringBootTest
class Springboot05MybatisApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
System.out.println(bookDao.getById(1));
}
}
总结
步骤①:导入对应的 starter 和数据库驱动
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
步骤②:配置数据源相关信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db
username: root
password: root
步骤③:配置表名的通用前缀名
数据库的表名定义规则是tbl_模块名称,为了能和实体类相对应,需要设置所有表名的通用前缀名
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_ #设置所有表的通用前缀名称为tbl_
步骤④:配置运行日志
通过配置运行日志就可以查阅执行时的SQL语句
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
id-type: auto
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #配置日志
测试
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
@Mapper
public interface BookDao extends BaseMapper<Book> {
}
核心在于Dao接口继承了一个BaseMapper的接口,这个接口中帮助开发者预定了若干个常用的API接口,简化了通用API接口的开发工作。
@SpringBootTest
class SpringbootApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
System.out.println(bookDao.selectById(2));
System.out.println(bookDao.selectList(null));
}
}
总结
前面整合 MyBatis 和 MyBatis-Plus 的时候,使用的数据源对象都是SpringBoot默认的数据源对象 HiKari,下面我们手工控制一下,自己指定了一个数据源对象 Druid。
步骤①:导入对应的starter
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
</dependencies>
步骤②:修改配置
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
username: root
password: root
#除了这4个常规配置外,还有druid专用的其他配置。通过提示功能可以打开druid相关的配置查阅
总结
步骤①:导入对应的 starter 和依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
步骤②:修改配置
spring:
redis:
host: 127.0.0.1 #指定redis所在的host
port: 6379 #指定redis的端口
password: 123456 #设置redis密码
lettuce:
pool:
max-active: 8 #最大连接数
max-idle: 8 #最大空闲数
min-idle: 0 #最小空闲数
max-wait: 100ms #连接等待时间
步骤③:使用springboot整合redis的专用客户端接口操作
@SpringBootTest
class SpringRedisApplicationTests {
@Resource
private RedisTemplate redisTemplate;
@Test
void testString() {
// 1.通过RedisTemplate获取操作String类型的ValueOperations对象
ValueOperations ops = redisTemplate.opsForValue();
// 2.插入一条数据
ops.set("name","jianjian");
// 3.获取数据,需要进行类型转换
String name = (String) ops.get("name");
System.out.println("name = " + name);
}
}
由于redis内部不提供java对象的存储格式,因此当操作的数据以对象的形式存在时,会进行转码,转换成字符串格式后进行操作。为了方便开发者使用基于字符串为数据的操作,springboot整合redis时提供了专用的API接口StringRedisTemplate,可以理解为这是RedisTemplate的一种指定数据泛型的操作API。
@SpringBootTest
public class StringRedisTemplateTest {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
void get(){
ValueOperations ops = stringRedisTemplate.opsForValue();
String name = ops.get("name");
System.out.println(name);
}
}
redis客户端选择
springboot整合redis技术提供了多种客户端兼容模式,默认提供的是lettuce客户端技术,也可以根据需要切换成指定客户端技术,例如jedis客户端技术,切换成jedis客户端技术操作步骤如下:
步骤①:导入jedis坐标
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
步骤②:配置客户端技术类型,设置为jedis
spring:
redis:
host: localhost
port: 6379
client-type: jedis
步骤③:根据需要设置对应的配置
spring:
redis:
host: localhost
port: 6379
client-type: jedis
lettuce:
pool:
max-active: 16
jedis:
pool:
max-active: 16
lettcus与jedis区别
docker pull rabbitmq:3-management
docker run \
-e RABBITMQ_DEFAULT_USER=jianjian \
-e RABBITMQ_DEFAULT_PASS=123321 \
--name mq \
--hostname mq1 \
-p 15672:15672 \
-p 5672:5672 \
-d rabbitmq:3-management
访问 http://127.0.0.1:15672
即可
导入springboot整合amqp的starter,amqp协议默认实现为rabbitmq方案
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
配置RabbitMQ的服务器地址
spring:
rabbitmq:
host: 127.0.0.1 # 主机名
port: 5672 # 端口
virtual-host: / # 虚拟主机
username: jianjian # 用户名
password: 123321 # 密码
案例
在consumer的SpringRabbitListener中添加两个消费者,同时基于注解来声明队列和交换机:
@Component
public class SpringRabbitListener {
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "direct.queue1"),
exchange = @Exchange(name = "jianjian.direct", type = ExchangeTypes.DIRECT),
key = {"red", "blue"}
))
public void listenDirectQueue1(String msg){
System.out.println("消费者接收到direct.queue1的消息:【" + msg + "】");
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "direct.queue2"),
exchange = @Exchange(name = "jianjian.direct", type = ExchangeTypes.DIRECT),
key = {"red", "yellow"}
))
public void listenDirectQueue2(String msg){
System.out.println("消费者接收到direct.queue2的消息:【" + msg + "】");
}
}
在publisher服务中添加测试方法:
@SpringBootTest
public class SpringAmqpTest {
@Test
public void testSendDirectExchange() {
// 交换机名称
String exchangeName = "jianjian.direct";
// 消息
String message = "红色警报!日本乱排核废水,导致海洋生物变异,惊现哥斯拉!";
// 发送消息
rabbitTemplate.convertAndSend(exchangeName, "red", message);
}
}
Quartz技术是一个比较成熟的定时任务框架。springboot对其进行整合后,简化了一系列的配置,将很多配置采用默认设置,这样开发阶段就简化了很多。 Quartz相关概念
简单说就是你定时干什么事情,这就是工作;工作不可能就是一个简单的方法,还要设置一些明细信息;工作啥时候执行,设置一个触发器;工作和触发器都是独立定义的,它们两个怎么配合到一起呢?用调度器。
步骤①:导入springboot整合Quartz的starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
步骤②:定义任务Bean,按照Quartz的开发规范制作,继承QuartzJobBean
public class MyQuartz extends QuartzJobBean { //工作
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.out.println("quartz task run...");
}
}
步骤③:创建Quartz配置类,定义工作明细(JobDetail)与触发器的(Trigger)bean
@Configuration
public class QuartzConfig {
@Bean
public JobDetail printJobDetail(){ //工作明细
//绑定具体的工作
return JobBuilder.newJob(MyQuartz.class).storeDurably().build();
}
@Bean
public Trigger printJobTrigger(){ //触发器
//调度器定义触发工作的执行规则 从0s开始每隔5s运行一次
ScheduleBuilder schedBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
//绑定对应的工作明细
return TriggerBuilder.newTrigger().forJob(printJobDetail()).withSchedule(schedBuilder).build();
}
}
工作明细中要设置对应的具体工作,使用newJob()操作传入对应的工作任务类型即可。
触发器需要绑定任务,使用forJob()操作传入绑定的工作明细对象。此处可以为工作明细设置名称然后使用名称绑定,也可以直接调用对应方法绑定。
触发器中最核心的规则是执行时间,此处使用调度器定义执行时间,执行时间描述方式使用的是cron表达式
。
cron表达式详解
在spring 4.x中已经不支持7个参数的cron表达式了,要求必须是6个参数。cron表达式格式如下:
{秒} {分} {时} {日期(具体哪天)} {月} {星期}
,
-
*
/
,,
表示特定的某一秒才会触发任务-
表示一段时间内会触发任务*
表示每一秒都会触发/
表示从哪一个时刻开始,每隔多长时间触发一次任务。?
,表示与{星期}互斥,即意味着若明确指定{星期}触发,则表示{日期}无意义,以免引起冲突和混乱。?
,表达的含义是与{日期}互斥,即意味着若明确指定{日期}触发,则表示{星期}无意义。总结
Spring Task是Spring 3.0自带的定时任务,可以将它看作成一个轻量级的Quartz,功能虽然没有Quartz那样强大,但是使用起来非常简单,无需增加额外的依赖,可直接上手使用。
步骤①:开启定时任务功能,在引导类上开启定时任务功能的开关,使用注解@EnableScheduling
@SpringBootApplication
@EnableScheduling //开启定时任务功能
public class SpringbootTaskApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot22TaskApplication.class, args);
}
}
步骤②:定义Bean,在对应要定时执行的操作上方,使用注解@Scheduled
定义执行的时间,执行时间的描述方式还是cron表达式
@Component
public class MyBean {
@Scheduled(cron = "0/1 * * * * ?")
public void print(){
System.out.println("spring task run...");
System.out.println(Thread.currentThread().getName()); //调度线程名 ssm_1
}
}
步骤③:如何想对定时任务进行相关配置,可以通过配置文件进行
spring:
task:
scheduling:
pool:
size: 1 # 任务调度线程池大小 默认 1
thread-name-prefix: ssm_ # 调度线程名称前缀 默认 scheduling-
shutdown:
await-termination: false # 线程池关闭时等待所有任务完成
await-termination-period: 10s # 调度线程关闭前最大等待时间,确保最后一定关闭
总结