版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jiangxishidayuan/article/details/52346419
1. Spring Data Redis
Redis是用一个基于内存的Key-Value数据库,而Jedis是Redis官方推出的面向Java的Client,提供了很多接口和方法,可以让Java操作使用Redis,而Spring Data Redis是对Jedis进行了封装,集成了Jedis的一些命令和方法,可以与Spring整合。在后面的配置文件(spring-context.xml)中可以看到,Spring是通过Jedis类来初始化connectionFactory的。
spring-data-redis针对jedis提供了如下功能:
1. 连接池自动管理,提供了一个高度封装的RedisTemplate类
2. 针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口 **RedisTemplate opsForXXX方法获得**
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作
序列化类:
GenericToStringSerializer: 可以将任何对象泛化为字符串并序列化
Jackson2JsonRedisSerializer: 跟JacksonJsonRedisSerializer实际上是一样的
JacksonJsonRedisSerializer: 序列化object对象为json字符串
JdkSerializationRedisSerializer: 序列化java对象
StringRedisSerializer: 简单的字符串序列化
3. 将事务操作封装,由容器控制。
1)操作代码
//实现序列化
public class User implements Serializable {
private int id;
private String name;
private String password;
public User() {
}
public User(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
//省去getter和setter方法
}
public interface UserService {
void add(User user);
User getUser(String key);
}
@Service
public class UserServiceImpl implements UserService {
//RedisTemplate
@Autowired
private RedisTemplate<String, User> redisTemplate;
@Override
public void add(User user) {
//第一种方法需要实现序列化,并在配置中配置序列化方式
// ValueOperations<String, User> valueOps = redisTemplate.opsForValue();
// valueOps.set(String.valueOf(user.getId()), user);
//第二种方式不用,调用ProtoStuff直接序列化
final byte[] key = ProtoStuffUtil.serialize(user.getId());
final byte[] value = ProtoStuffUtil.serialize(user);
boolean result = redisTemplate.execute((RedisConnection connection) -> {
return connection.setNX(key, value);
});
System.out.println("添加的结果: " + result);
}
@Override
public User getUser(String key) {
// ValueOperations<String, User> valueOps = redisTemplate.opsForValue();
// return valueOps.get(key);
byte[] result = redisTemplate.execute((RedisConnection connection) -> {
return connection.get(ProtoStuffUtil.serialize(Integer.valueOf(key)));
});
if(result == null)
return null;
return ProtoStuffUtil.deserialize(result, User.class);
}
}
@Controller
@RequestMapping("/redis")
public class UserController {
@Autowired
private UserService userService;
private User user;
@RequestMapping(value="/addUser", method= RequestMethod.POST)
public String addUser(@RequestParam(value="id") String id,
@RequestParam(value="name") String name,
@RequestParam(value="password") String password) {
user = new User(Integer.valueOf(id), name, password);
userService.add(user);
return "addSuccess";
}
@RequestMapping(value="/addUser", method=RequestMethod.GET)
public String addUser() {
return "addUser";
}
@RequestMapping(value = "/queryUser")
public String queryUser() {
return "getUser";
}
@RequestMapping(value = "/getUser")
public String getUser(
@RequestParam(value = "key", required = true) String key,Model model) {
user = userService.getUser(key); //null判断
model.addAttribute("userId", user.getId());
model.addAttribute("username", user.getName());
model.addAttribute("userpassword", user.getPassword());
return "showUser";
}
}
2. 定时任务Spring Quartz
- Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。
- Quartz,这是一个功能比较强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行。
- Spring自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。
1)作业类的继承方式
- 作业类需要继承自特定的作业类基类,如java.util.Timer中需要继承自java.util.TimerTask。
- 作业类即普通的java类,不需要继承自任何基类。
2)任务调度的触发时机
- 每隔指定时间则触发一次
- 每到指定时间则触发一次
//操作步骤
一、创建任务(Job)
一种是继承org.springframework.scheduling.quartz.QuartzJobBean类来实现Job任务
另一种是不继承任何类,创建普通的Java类,然后自己指定任务的执行方法。
二、在Spring配置文件中配置JobDetail
三、配置触发器(Trigger)
1、org.springframework.scheduling.quartz.SimpleTriggerFactoryBean(此种方式是隔多长时间进行触发一次,比如每隔24小时触发一次)
2、org.springframework.scheduling.quartz.CronTriggerFactoryBean(此种方式是在指定的时间进行触发,比如只在周一进行触发)
四、配置SchedulerFactoryBean
时间格式:
1)Cron表达式的格式:秒 分 时 日 月 周 年(可选)。
字段名 允许的值 允许的特殊字符
秒 0-59 , - * /
分 0-59 , - * /
小时 0-23 , - * /
日 1-31 , - * ? / L W C
月 1-12 or JAN-DEC , - * /
周 1-7 or SUN-SAT , - * ? / L C #
年 (可选字段) empty, 1970-2099 , - * /
“*”字符:表示该域上的每一个值
“?”字符:表示不确定的值
“,”字符:指定数个值
“-”字符:指定一个值的范围
“/”字符:指定一个值的增加幅度。n/m表示从n开始,每次增加m
“L”字符:用在日表示一个月中的最后一天,用在周表示该月最后一个星期X
“W”字符:指定离给定日期最近的工作日(周一到周五)
“#”字符:表示该月第几个周X。6#3表示该月第3个周五
2)Cron表达式范例:
每隔5秒执行一次:*/5 * * * * ?
每隔1分钟执行一次:0 */1 * * * ?
每天23点执行一次:0 0 23 * * ?
每天凌晨1点执行一次:0 0 1 * * ?
每月1号凌晨1点执行一次:0 0 1 1 * ?
每月最后一天23点执行一次:0 0 23 L * ?
每周星期天凌晨1点实行一次:0 0 1 ? * L
在26分、29分、33分执行一次:0 26,29,33 * * * ?
每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?
在Spring配置和Quartz集成内容时,有两点需要注意
1、在<Beans>
中不能够设置default-lazy-init=”true”,否则定时任务不触发,如果不明确指明default-lazy-init的值,默认是false。
2、在<Beans>
中不能够设置default-autowire=”byName”的属性,否则后台会报org.springframework.beans.factory.BeanCreationException错误,这样就不能通过Bean名称自动注入,必须通过明确引用注入
3)注解配置
- @Component配置Job
- @Scheduled配置调度策略
//每隔三秒执行一次
@Scheduled(cron = "0/5 * * * * ?")
- xml文件中配置task
xmlns:task="http://www.springframework.org/schema/task"
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd
- task注解驱动
<!--开启这个配置,spring才能识别@Scheduled注解-->
<task:annotation-driven/>