【问题标题】:Can we add spring boot cacheable method inside scheduled cache evict method for application safety?为了应用程序安全,我们可以在计划的缓存驱逐方法中添加 Spring Boot 可缓存方法吗?
【发布时间】:2019-02-16 00:02:49
【问题描述】:

我正在尝试实现 Spring Boot 可缓存。我想缓存 ws 调用的方法响应。

1) 我可以根据请求实现缓存。

 @Cacheable(cacheNames = "mycache", key = "#root.target.cacheKey")
   public String myMethod() {
}

2) 我在每天凌晨 1 点之后安排缓存驱逐。

@Scheduled(cron = "${1 AM}")
    @CacheEvict(cacheNames = "mycache", key = "#root.target.CACHE_KEY")
    public void clearCache() {

        LOGGER("Cache eviction:: ");

    }

这也很好用。 我的问题是在没有浏览器对 @Cacheable 注释方法的任何请求的情况下驱逐之后,我可以在驱逐后调用 @Cacheable 注释方法来确保应用程序安全吗?

@Scheduled(cron = "${1 AM}")
        @CacheEvict(cacheNames = "mycache", key = "#root.target.CACHE_KEY")
        public void clearCache() {

            LOGGER("Cache eviction:: ");
        myMethod();
        }

这是为了应用程序安全。以防 @Cacehable 无法缓存 响应它不会影响应用程序。我首先同意 驱逐后的请求肯定会进入 @Cacheable 注释 方法并添加到缓存中。但需要确保我遵循 正确的方法

有人可以解释一下,以便对我更正有用

【问题讨论】:

  • 我不明白你为什么要这么做。你的申请会很好
  • 是的,我明白了.. 如果假设后端有更新。缓存没有更新后的数据驱逐。在这种情况下,只有在第一次请求时才能缓存它即时的。我不想冒这个风险
  • 看我的回答。应该足够详细

标签: java spring-boot caching


【解决方案1】:

所以,我正在查看来源。

@CacheEvict AspectJ pointcut 定义为

/**
 * Matches the execution of any public method in a type with the @{@link CacheEvict}
 * annotation, or any subtype of a type with the {@code CacheEvict} annotation.
 */
private pointcut executionOfAnyPublicMethodInAtCacheEvictType() :
    execution(public * ((@CacheEvict *)+).*(..)) && within(@CacheEvict *);

然后组合成一个更通用的

protected pointcut cacheMethodExecution(Object cachedObject) :
    (executionOfAnyPublicMethodInAtCacheableType()
            || executionOfAnyPublicMethodInAtCacheEvictType()
            || ...

使用此pointcutadvicearound 建议,这意味着您可以检查方法调用的输入和输出值,并在需要时继续进行实际调用。

Object around(final Object cachedObject) : cacheMethodExecution(cachedObject) {
    MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
    Method method = methodSignature.getMethod();

    CacheOperationInvoker aspectJInvoker = new CacheOperationInvoker() {
        public Object invoke() {
            try {
                // Call your method implementation
                return proceed(cachedObject);
            }
            catch (Throwable ex) {
                throw new ThrowableWrapper(ex);
            }
        }
    };

    try {
        // Evict cache, in your case
        return execute(aspectJInvoker, thisJoinPoint.getTarget(), method, thisJoinPoint.getArgs());
    }
    catch (CacheOperationInvoker.ThrowableWrapper th) {
        AnyThrow.throwUnchecked(th.getOriginal());
        return null; // never reached
    }
}

如你所见,方法实现是用proceed调用的通过调用execute执行缓存逐出操作之前。

因此,您的“测试”调用没有实际意义。

【讨论】:

  • 感谢您的详细解释。
猜你喜欢
  • 2011-04-12
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多