1. Spring Boot整合Spring Data Redis-整合步骤
(1)阐述Spring Boot整合Spring Data Redis整合步骤。
创建项目,修改pom文件,配置全局配置文件,创建启动类
<!-- springBoot 的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- web 启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Spring Data Redis 的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
(2)@Configuration注解的作用是什么?
当前文件作为配置类
(3)@Bean注解的作用是什么?
将对象注入spring容器中
2.Spring Boot整合Spring Data Redis-提取Redis的链接参数
(1)@ConfigurationProperties注解的作用是什么?
@ConfigurationProperties:会将前缀相同的内容创建一个实体
(2)@ConfigurationProperties注解中的prefix属性的作用是什么?
指定前缀内容
3.Spring Boot整合Spring Data Redis-存取Java对象
(1)创建Users实体对象,包含id、name、age、address属性。
public class Users implements Serializable{
private Integer id;
private String name;
private Integer age;
private String address;
}
(2)创建测试代码,在测试方法中重新设置序列化器,更换为jdk序列化器,
(3)并将Users对象缓存到Redis中。
(4)创建测试代码,获取缓存的Users对象。
/**
* 完成对Redis的整合的一些配置
*
* @author chy
*
*/
@Configuration
public class RedisConfig {
/**
* 1.创建JedisPoolConfig 对象。在该对象中完成一些链接池配置
* @ConfigurationProperties:会将前缀相同的内容创建一个实体。
*/
@Bean
@ConfigurationProperties(prefix="spring.redis.pool")
public JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig config = new JedisPoolConfig();
//最大空闲数
//config.setMaxIdle(10);
//最小空闲数
//config.setMinIdle(5);
//最大链接数
//config.setMaxTotal(20);
System.out.println("默认值:"+config.getMaxIdle());
System.out.println("默认值:"+config.getMinIdle());
System.out.println("默认值:"+config.getMaxTotal());
return config;
}
/**
* 2.创建JedisConnectionFactory:配置redis链接信息
*/
@Bean
@ConfigurationProperties(prefix="spring.redis")
public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig config){
System.out.println("配置完毕:"+config.getMaxIdle());
System.out.println("配置完毕:"+config.getMinIdle());
System.out.println("配置完毕:"+config.getMaxTotal());
JedisConnectionFactory factory = new JedisConnectionFactory();
//关联链接池的配置对象
factory.setPoolConfig(config);
//配置链接Redis的信息
//主机地址
//factory.setHostName("192.168.179.131");
//端口
//factory.setPort(6379);
return factory;
}
/**
* 3.创建RedisTemplate:用于执行Redis操作的方法
*/
@Bean
public RedisTemplate<String,Object> redisTemplate(JedisConnectionFactory factory){
RedisTemplate<String, Object> template = new RedisTemplate<>();
//关联
template.setConnectionFactory(factory);
//为key设置序列化器
template.setKeySerializer(new StringRedisSerializer());
//为value设置序列化器
template.setValueSerializer(new StringRedisSerializer());
return template;
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=App.class)
public class TestRedis {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 插入一个字符串
*/
@Test
public void TestSet() {
this.redisTemplate.opsForValue().set("name", "乔鲁诺乔斯达");
}
/**
* 从redis中取值
*/
@Test
public void TestGet() {
String name = (String) this.redisTemplate.opsForValue().get("name");
System.out.println(name);
}
/**
* 设置Users对象
*注意通过: JdkSerializationRedisSerializer序列化器所占内存较大
*/
@Test
public void TestObjectSet() {
Users users = new Users();
users.setId(1);
users.setName("乔鲁诺乔巴纳");
users.setAge(16);
users.setAddress("意大利罗马");
this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
this.redisTemplate.opsForValue().set("Users", users);
}
/**
* 获取Users对象
*注意通过: JdkSerializationRedisSerializer序列化器所占内存较大
*/
@Test
public void TestObjectGet() {
this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
Users users = (Users) this.redisTemplate.opsForValue().get("Users");
System.out.println(users);
}
/**
* 设置Users对象,通过Json序列化器
*占用内存较小
*/
@Test
public void TestObjectSetJson() {
Users users = new Users();
users.setId(1);
users.setName("乔鲁诺乔巴纳");
users.setAge(16);
users.setAddress("意大利罗马");
this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
this.redisTemplate.opsForValue().set("Users_Json", users);
}
/**
* 获取Users对象,通过Json序列化器
*占用内存较小
*/
@Test
public void TestObjectGetJson() {
this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
Users users = (Users) this.redisTemplate.opsForValue().get("Users_Json");
System.out.println(users);
}
}
4.Spring Boot定时任务-@Scheduled的使用
(1)Scheduled是什么?
//不属于控制层、服务层、数据访问层。所以使用@Component
@Component
public class ScheduledDemo {
/**
* 每两秒打印一次时间
* cron="0/2 * * * * *"
*
* 每分钟的第二秒打印一次时间
* cron="2 * * * * *"
*/
@Scheduled(cron="0/2 * * * * ?")
public void doScheduled() {
System.out.println("定时器:"+new Date());
}
}
(2)@Scheduled注解的作用是什么?
开启定时任务
(3)@Scheduled的cron属性的作用是什么?
指定定时器规则
(4)什么是cron表达式?
Cron 表达式是一个字符串,分为6 或7 个域,每一个域代表一个含义
Cron 有如下两种语法格式:
(1) Seconds Minutes Hours Day Month Week Year
(2) Seconds Minutes Hours Day Month Week(推荐使用)
(5)@EnableScheduling注解的作用是什么?
在开启启动类时,需要额外加@EnableScheduling注解
5.Spring Boot定时任务-cron表达式
(1)Cron表达式的语法格式有几种?
六种和七种
1)Seconds Minutes Hours Day Month Week Year
2)Seconds Minutes Hours Day Month Week
(2)Cron表达式的结构是什么样的?
corn 从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份
(3)Cron表达式各字段的含义是什么?
(4)在Cron表达式中(*)、(?)、(-)、(,)、(/)、(#)分别表示什么含义?
●星号(*):可用在所有字段中,表示对应时间域的每一个时刻,例如,在分钟字段时,表示“每分钟”;
●问号(?):该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于占位符;
●减号(-):表达一个范围,如在小时字段中使用“10-12”,则表示从 10 到 12 点,即 10,11,12;
●逗号(,):表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期 五;
●斜杠(/):x/y 表达一个等步长序列,x 为起始值,y 为增量步长值。如在分钟字段中使用 0/15,则 表示为 0,15,30 和 45 秒,而 5/15 在分钟字段中表示 5,20,35,50,你也可以使用/y,它等同于 0/y
(5)在Cron表达式中L、W、LW、C分别表示什么含义?
●L:该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。L 在日期 字段中,表示这个月份的最后一天,如一月的 31 号,非闰年二月的 28 号;如果 L 用在星期中,则表示星 期六,等同于 7。但是,如果 L 出现在星期字段里,而且在前面有一个数值 X,则表示“这个月的最后 X 天”, 例如,6L 表示该月的最后星期五;
●W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如 15W 表示离该月 15 号最近的工作日,如果该月 15 号是星期六,则匹配 14 号星期五;如果 15 日是星期日, 则匹配 16 号星期一;如果 15 号是星期二,那结果就是 15 号星期二。但必须注意关联的匹配日期不能够 跨月,如你指定 1W,如果 1 号是星期六,结果匹配的是 3 号星期一,而非上个月最后的那天。W 字符串 只能指定单一日期,而不能指定日期范围;
●LW 组合:在日期字段可以组合使用 LW,它的意思是当月的最后一个工作日;
6.Spring Boot定时任务-Quartz介绍
(1)什么是Quartz?
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.0。
(2)Quartz的使用思路是什么?
创建定时任务,启动定时任务
7.Spring Boot定时任务-SpringBoot整合Quartz
(1)阐述Spring Boot整合Quartz整合步骤。
1.创建项目,导入依赖
2.修改全局配置文件
3.创建启动类
(2)@EnableScheduling注解的作用是什么?
开启定时器
8.Spring Boot定时任务-Job类对象注入
(1)阐述Job类注入时生异常的原因。
在quartz中定时任务的创建时通过AdaptableJobFactory类中的createJobInstance方法创建,使用的是反射,没有使用spring,所以无法注入对象。
(2)如何解决该异常?
复写createJobInstance方法,将创建的定时任务加入到spring容器中。
(3)AutowireCapableBeanFactory对象的作用是什么?
可以将一个对象添加到SpringIOC 容器中,并且完成该对象注入
9. 单体架构
(1)什么是单体架构?
就是一种把系统中的所有功能,模块耦合在一个应用中的架构。也称之单体系统或单体应用
(2)单体架构有哪些特点?
1.打包成独立的单元(jar包或者war包)
2.会以一个进程的方式运行
(3)单体架构的优缺点是什么?
优点:1.项目部署简单 2.项目易于管理
缺点:1.测试成本高 2.可伸缩性差 3.可靠性差 4.迭代困难 5.跨语言性能差 6.团队协作难
10.微服务架构
(1)什么是微服务?
微服务是一种架构风格。一个大型的复杂软件应用,由一个或多个微服务组成。系统中 的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任 务并很好的完成该任务
(2)常见的架构风格有哪些?
客户端与服务器端
基于组件模型
分层架构
面向服务
(3)微服务架构有哪些特点?
系统有多个服务组成,每个服务单独的部署,服务之间是松耦合,服务内部是高内聚的,外部是低耦合的
(4)微服务架构的优缺点是什么?
测试容易,可靠性强,跨语言更加灵活
11.常见软件架构方式的区别
(1)什么是MVC架构?
是一个单体架构
(2)什么是RPC架构?
远程过程调用。他一种通过网络从远程计算机程序上请求 服务,而不需要了解底层网络技术的协议。
(3)什么是SOA架构?
面向服务架构
12.AKF拆分原则
(1)设计微服务的原则是什么?
AKF拆封原则
前后端分离原则
无状态服务
ResultFul的通信风格
(2)什么是AKF拆分原则?
添加容器来解决容量和可用性的问题
(3)AKF拆分原则中的Y轴表示什么?
按照功能划分,基于不同的业务划分
(4)AKF拆分原则中的X轴表示什么?
加机械解决问题
(5)AKF拆分原则中的Z轴表示什么?
关注服务和数据的优先级
13.前后端分离原则
(1)什么是前后端分离原则?
就是前端和后端的代码分离
14.无状态服务
(1)什么是无状态服务?
一条数据需要被多个服务共享,才能完成一笔交易的,这个数据称之为状态,依赖这个数据的服务称之无状态服务