接续上一篇,spring boot 、mybatis-plus、shiro整合入门教程(三)——shiro使用
在使用shiro进行spring boot、mybatis-plus的整合中,使用了日志注解、缓存注解,主要原理利用了AOP切面进行的开发,代码如下:
/**
* @author liuyi
* @date 2019/5/20
*
* 缓存注解
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cache {
/**
* 缓存key
* @return
*/
String cacheKey() default "";
/**
* 过期时间 minute
* @return
*/
String expired() default "60";
}
/**
* @author liuyi
* @date 2019/5/16
*
* 系统日志注解
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SysLog {
String value() default "";
}
/**
* @author liuyi
* @date 2019/5/20
*
* 缓存注解切面
*/
@Component
@Aspect
@Slf4j
public class CacheAspect implements Ordered {
@Resource
private RedisTemplate redisTemplate;
public CacheAspect() {
}
@Around("@annotation(com.agile.demo.common.annotation.Cache)")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
String clazz = pjp.getTarget().getClass().getSimpleName();
String methodName = pjp.getSignature().getName();
Class[] paramTypes = ((MethodSignature) pjp.getSignature()).getParameterTypes();
Object[] args = pjp.getArgs();
log.debug("Invoke {}.{}({})", clazz, methodName, args);
Method method = pjp.getTarget().getClass().getMethod(methodName, paramTypes);
Cache cache = method.getAnnotation(Cache.class);
byte[] cacheKey = null;
String cacheKeys = cache.cacheKey();
if (StringUtils.isBlank(cacheKeys)) {
StringBuilder sb = new StringBuilder();
sb.append(clazz).append(":").append(CacheKeyGenerator.getMethodLongName(method)).append(":").append(
JSON.toJSONString(args));
cacheKey = sb.toString().getBytes();
} else {
cacheKey = CacheKeyGenerator.generate(cacheKeys, args).getBytes();
}
Object result = null;
boolean invokeProxy = true;
try {
String expired = cache.expired();
String value = (String)redisTemplate.opsForValue().get(cacheKey);
if (StringUtils.isBlank(value)) {
try {
result = pjp.proceed();
} catch (Exception e) {
invokeProxy = false;
throw e;
}
redisTemplate.opsForValue().set(cacheKey, value, Long.parseLong(expired), TimeUnit.MINUTES);
return result;
} else {
return value;
}
} catch (Exception e) {
log.error(e.getMessage(), e);
if (invokeProxy) {
//当redis服务异常时,直接调被代理方法
return pjp.proceed();
}
throw e;
}
}
@Override
public int getOrder() {
return 1;
}
}
/**
* @author liuyi
* @date 2019/5/16
*
* 系统日志切面
*/
@Aspect
@Component
public class SysLogAspect {
@Resource
private HttpServletRequest request;
@Resource
private SysLogServiceImpl sysLogService;
@Pointcut("@annotation(com.agile.demo.common.annotation.SysLog)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
long beginTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long time = System.currentTimeMillis() - beginTime;
saveSysLog(joinPoint, time);
return result;
}
/**
* 系统保存日志
* @param joinPoint
* @param time
* @throws Throwable
*/
private void saveSysLog(ProceedingJoinPoint joinPoint, long time) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
com.agile.demo.common.annotation.SysLog log = signature.getMethod().getAnnotation(com.agile.demo.common.annotation.SysLog.class);
Object[] args = joinPoint.getArgs();
SysLog sysLog = new SysLog();
if (log != null) {
sysLog.setOperation(log.value());
}
sysLog.setParams(JSON.toJSONString(args[0]));
sysLog.setCreateDate(LocalDateTime.now());
sysLog.setIp(IPUtils.getIpAdrress(request));
sysLog.setMethod(joinPoint.getTarget().getClass().getName() + "." + signature.getName());
sysLog.setTime(time);
sysLog.setUsername(((SysUser) SecurityUtils.getSubject().getPrincipal()).getUsername());
sysLogService.save(sysLog);
}
}