springboot2
下面的pom.xml
org.redisson
redisson
3.11.0
另外添加aop,为后面添加注释做准备
org.springframework.boot
spring-boot-starter-aop
创建2个类,用于管理redis
/**
* 创建redis锁的类
* @author wangmin33
*
*/
public class DistributedRedisLock {
private static final Logger LOGGER = LoggerFactory.getLogger(DistributedRedisLock.class);
// 从配置类中获取redisson对象
private static Redisson redisson = RedissonManager.getRedisson();
private static final String LOCK_TITLE = "redisLock_";
private static String ip;//计划使用ip区分,后来没用
static {
InetAddress localHost = null;
try {
localHost = Inet4Address.getLocalHost();
} catch (UnknownHostException e) {
LOGGER.error(e.getMessage(),e);
}
ip = localHost.getHostAddress(); // 返回格式为:xxx.xxx.xxx
}
// 加锁,一直等待获得锁
public static boolean acquire(String lockName) {
// 声明key对象
String key = LOCK_TITLE + lockName;
// 获取锁对象
RLock mylock = redisson.getLock(key);
// 加锁,并且设置锁过期时间,防止死锁的产生
//加锁 锁的有效期默认30秒
mylock.lock(2, TimeUnit.MINUTES);
LOGGER.info(key+"======lock======" + Thread.currentThread().getName());
// 加锁成功
return true;
}
// 锁的释放
public static void release(String lockName) {
// 必须是和加锁时的同一个key
String key = LOCK_TITLE + lockName;
// 获取所对象
RLock mylock = redisson.getLock(key);
// 释放锁(解锁)
mylock.unlock();
LOGGER.info(key+"======unlock======" + Thread.currentThread().getName());
}
//尝试获取锁,如果获取不到就放弃
public static boolean tryLock(String lockKey){
// 声明key对象
String key = LOCK_TITLE + lockKey;
RLock lock = redisson.getLock(key);
/**
* tryLock()方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false .
*/
// 加锁,并且设置锁过期时间,防止死锁的产生
LOGGER.info(key+"======trylock======" + Thread.currentThread().getName());
boolean islock=false;
try {
islock=lock.tryLock(1,120,TimeUnit.SECONDS);
} catch (InterruptedException e) {
LOGGER.info("error" + e.getMessage());
}
return islock;
}
/**
* 尝试获取锁,
* @param lockKey
* @param unit 等待时间的单位
* @param waitTime 等待获取锁的时间
* @param leaseTime 释放的时间
* @return
*/
public static boolean tryLock(String lockKey,TimeUnit unit,long waitTime,long leaseTime){
// 声明key对象
String key = LOCK_TITLE + lockKey;
RLock lock = redisson.getLock(key);
try{
lock.tryLock(waitTime,leaseTime,unit);
return true;
}catch (InterruptedException e){
LOGGER.info("error" + e.getMessage());
return false;
}
}
}
/**
* 连接redis
* @author wangmin33
*
*/
public class RedissonManager {
private static Config config = new Config();
// 声明redisso对象
private static Redisson redisson = null;
// 实例化redisson
static {
config.useSingleServer().setAddress("redis://10.10.1.96:1111");
config.useSingleServer().setPassword("33333");
// 得到redisson对象
redisson = (Redisson) Redisson.create(config);
}
private RedissonManager() {};
// 获取redisson对象的方法
public static Redisson getRedisson() {
return redisson;
}
}
创建controller类进行测试
package com.wang.redis.controller;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.wang.redis.service.RedisService;
import com.wang.redis.util.DistributedRedisLock;
@Controller
@RequestMapping("keepup")
public class KeepupController {
private static final Logger LOGGER = LoggerFactory.getLogger(KeepupController.class);
@Autowired
private RedisService redisService;
@Value("${redis.key}")
private String redis_key;
@RequestMapping("/redder")
@ResponseBody
public String redder() throws IOException {
// 加锁
boolean lock = DistributedRedisLock.tryLock(redis_key);
if (lock) {
// 执行具体业务逻辑
LOGGER.info("aaaa222222");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
}
// 释放锁
DistributedRedisLock.release(redis_key);
} else {
LOGGER.info("aaaa22222222放弃执行");
}
// 返回结果
return "end";
}
@RequestMapping("/redder2")
@ResponseBody
public String redder2() throws IOException {
// 加锁
boolean lock = DistributedRedisLock.tryLock(redis_key);
if (lock) {
// 执行具体业务逻辑
LOGGER.info("aaaa33333");
// 释放锁
DistributedRedisLock.release(redis_key);
} else {
LOGGER.info("aaaa33333放弃执行");
}
// 返回结果
return "end";
}
@RequestMapping("/redder3")
@ResponseBody
public String redder3() throws IOException {
redisService.run("3333333333");
// 返回结果
return "end";
}
@RequestMapping("/redder4")
@ResponseBody
public String redder4() throws IOException {
redisService.run("44444444444");
// 返回结果
return "end";
}
}
service
@RedisAnnotation
public void run(String name) {
// 执行具体业务逻辑
LOGGER.info(name);
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
添加自定义注解
package com.wang.redis.aop;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Target;
/**
* @Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
* @author wangmin33
*
*/
@Documented//说明该注解将被包含在javadoc中
//@Target:定义注解的作用目标
@Target({ElementType.METHOD,ElementType.PARAMETER})// 方法和方法参数
@Inherited//说明子类可以继承父类中的该注解
public @interface RedisAnnotation {
/**
* 如果注解只有一个属性,那么肯定是赋值给该属性。
* 如果注解有多个属性,而且前提是这多个属性都有默认值,那么你不写注解名赋值,会赋值给名字为“value”这属性。
* 如果注解有多个属性,其中有没有设置默认值的属性,那么当你不写属性名进行赋值的时候,是会报错的。
*/
//@AliasFor("")起别名
int value() default 000;
}
添加aop
package com.cloud.keepup.aop;
import java.util.HashMap;
import java.util.Map;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.cloud.keepup.controller.KeepupController;
import com.util.DistributedRedisLock;
/**
* 自定义切面类:@Component必须要添加,否则无效
*
* <!-- 开启AspectJ自动代理--> <aop:aspectj-autoproxy />
*/
@Component
@Aspect
public class RedisAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(RedisAspect.class);
@Value("${redis.key}")
private String redis_key;
@Pointcut("@annotation(com.cloud.keepup.aop.RedisAnnotation)")
public void cut() {
}
@Around(value = "cut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前通知==========");
// 加锁
Object obj = null;
boolean lock = DistributedRedisLock.tryLock(redis_key);
if (lock) {
obj = joinPoint.proceed();
// 释放锁
DistributedRedisLock.release(redis_key);
} else {
LOGGER.info("aaaa22222222放弃执行");
}
System.out.println("环绕后通知==========");
return obj;
}
}
在application里面添加
redis.key=test123