多数据源内部方法调用切面失效的问题

今天在使用Spring cache的Cacheable注解的过程中遇见了一个Cacheable注解失效的问题,检查问题发生的原因是因为Spring的Cacheable注解是基于Spring AOP实现的,但是类内部方法互相调用时不会被Spring AOP拦截的,所以导致被调用方法的Cacheable注解失效

问题复现

多数据源内部方法调用切面失效的问题_第1张图片

 

多数据源内部方法调用切面失效的问题_第2张图片

多数据源内部方法调用切面失效的问题_第3张图片

以上写法切面失效

问题解决

  • 写一个工具类SpringContextUtil实现ApplicationContextAware接口
  • public class SpringContextUtil implements ApplicationContextAware {
        private static ApplicationContext applicationContext;
        
        @Override
        public void setApplicationContext(ApplicationContext applicationContext){
            SpringContextUtil.applicationContext = applicationContext;
        }
        
        public static ApplicationContext getApplicationContext(){
            return applicationContext;
        }
        
        public static Object getBean(Class var1) throws BeansException {
            return applicationContext.getBean(var1);
        }
    }
  • Spring Boot启动的时候将ApplicationContext注入SpringContextUtil
 
  • 在UserServiceImpl方法中使用
  • @Override
        public List collect(LocalDateTime startTime, LocalDateTime endTime) {
            List list = new ArrayList<>();
            LocalDateTime curTime = LocalDateTime.now();
            LocalDateTime lastTime = curTime.minus(3L, ChronoUnit.MINUTES);
            // 注入当前Bean使得调用内部方法也被SpringAOP拦截
            AuditCollectService auditCollectService = (AuditCollectService) SpringContextUtil.getBean(this.getClass());
            if (null != startTime && null != endTime) { // 有参
                lastTime = startTime;
                curTime = endTime;
                list = auditCollectService.qryInfos(lastTime, curTime);
            } else { // 无参
                String time = redisService.get("audit_ugc_collect_time");
                if (time != null && !"".equals(time)) {
                    lastTime = LocalDateTime.parse(time.split(",")[1]);
                }
                list = auditCollectService.qryInfos(lastTime, curTime);
                this.redisService.set("audit_ugc_collect_time", lastTime.toString() + "," + curTime.toString());

            }

            // 数据采集中间存储
            this.saveHis(list, curTime);
            return list;
        }

  • 这样就可以解决Bean内部方法调用不被Spring AOP拦截的问题

 

你可能感兴趣的:(框架,JAVASE,JAVAEE)