1.注解方式开启Spring二级缓存
1.1主启动类
`@EnableCaching`
1.2 需要加注解的方法
在serviceimpl层加
查询:@Cacheable(value="userList")
新增:@CacheEvict(value="userList",allEntries = true)
1.3 @Cacheable、@CacheEvict、@CachePut 解析
1.31@Cacheable
@Cacheable可以标记在一个方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。对于一个支持缓存的方法,Spring会在其被调用后将其返回值缓存起来,以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。Spring在缓存方法的返回值时是以键值对进行缓存的,值就是方法的返回结果,至于键的话,Spring又支持两种策略,默认策略和自定义策略,这个稍后会进行说明。需要注意的是当一个支持缓存的方法在对象内部被调用时是不会触发缓存功能的。@Cacheable可以指定三个属性,value、key和condition。
– value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。
– key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。
– 有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能。condition属性默认为空,表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。如下示例表示只有当user的id为偶数时才会进行缓存。
1.32@CacheEvict
@CacheEvict是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的语义与@Cacheable对应的属性类似。即value表示清除操作是发生在哪些Cache上的(对应Cache的名称);key表示需要清除的是哪个key,如未指定则会使用默认策略生成的key;condition表示清除操作发生的条件。下面我们来介绍一下新出现的两个属性allEntries和beforeInvocation。
– allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。
– 清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。
1.33@CachePut
在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。
与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
@CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟@Cacheable是一样的。
@CachePut(“users”)//每次都会执行方法,并将结果存入指定的缓存中
使用AOP查看方法执行时间
1.配置LogAspect
@Aspect
@Component
public class LogAspect {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Pointcut("execution(public * com.xxxx.xxxx.Controller.*.*(..))")
public void LogAspect() {
}
/** * 前置通知 * * @param joinPoint 切入点 */
@Before("LogAspect()")
public void doBefore(JoinPoint joinPoint) {
}
/** * 后置通知 * * @param joinPoint 切入点 */
@After("LogAspect()")
public void doAfter(JoinPoint joinPoint) {
}
/** * 最终通知 * * @param joinPoint 切入点 */
@AfterReturning("LogAspect()")
public void doAfterReturning(JoinPoint joinPoint) {
}
/** * 异常通知 * * @param joinPoint 切入点 */
@AfterThrowing("LogAspect()")
public void deAfterThrowing(JoinPoint joinPoint) {
// 出现异常
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Object[] args = joinPoint.getArgs();//获取参数数组
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("\n出现异常信息");
stringBuilder.append("\n###请求URL: " + request.getRequestURL().toString());
stringBuilder.append("\n ###IP: " + request.getRemoteAddr());
stringBuilder.append("\n ###Params: " + Arrays.toString(args));
logger.warn(stringBuilder.toString());
}
/** * 环绕通知 * * @param joinPoint 切点 * @return * @throws Throwable */
@Around("LogAspect()")
public Object deAround(ProceedingJoinPoint joinPoint) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
long startTime = System.currentTimeMillis();//开始时间
Object[] args = joinPoint.getArgs();//获取参数数组
Object ret = joinPoint.proceed(args);//执行原方法并获取返回结果
long endTime = System.currentTimeMillis();//结束时间
// 记录下请求内容
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("\n###请求URL: " + request.getRequestURL().toString());
stringBuilder.append("\n ###IP: " + request.getRemoteAddr());
stringBuilder.append("\n ###Params: " + Arrays.toString(args));
stringBuilder.append("\n ###CLASS_METHOD: " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
stringBuilder.append("\n ###耗时: " + (endTime - startTime) + "毫秒");
logger.info(stringBuilder.toString());
return ret;
}
}
今天的文章Spring二级缓存分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/11225.html