简体   繁体   English

Spring @CacheEvict行为

[英]Spring @CacheEvict Behavior

I am trying to understand the behavior of @CacheEvict in Spring Cache Abstraction. 我试图了解Spring Cache Abstraction中@CacheEvict的行为。 Here is my sample application 这是我的示例应用程序

pom.xml pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

Application 应用

@SpringBootApplication
@EnableCaching
public class Application implements ApplicationListener<ApplicationReadyEvent>  {
    private final OrderService orderService;
    public Application (OrderService orderService) {
        this.orderService = orderService;
    }
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        List<Order> orders = orderService.getPendingOrders();
        System.out.println("Found " + orders.size() + " Pending Orders.");
        orderService.fulFillOrder(orders.stream().findFirst().get());
        orders = orderService.getPendingOrders();
        System.out.println("Found " + orders.size() + " Pending Orders.");
    }
}

Model 模型

public class Order {
    final int id;
    final int qty;
    final String status;
    Order (int id, int qty, String status) {
        this.id = id;
        this.qty = qty;
        this.status = status;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Order order = (Order) o;
        if (id != order.id) return false;
        if (qty != order.qty) return false;
        return status.equals(order.status);
    }
    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + qty;
        result = 31 * result + status.hashCode();
        return result;
    }
}

Service 服务

@Service
public class OrderService {
    @Cacheable("pendingOrders")
    public List<Order> getPendingOrders() {
        System.out.println("Creating Orders... Expensive Operation...");
        List<Order> pendingOrders = new ArrayList<>();
        pendingOrders.add(new Order(1, 10, "PENDING"));
        pendingOrders.add(new Order(2, 10, "PENDING"));
        return Collections.unmodifiableList(pendingOrders);
    }

    @CacheEvict("pendingOrders")
    public void fulFillOrder(Order order) {

        System.out.println("Fulfilling Order...");
    }
}

Actual Output 实际产量

Creating Orders... Expensive Operation...
Found 2 Pending Orders.
Removing Order...
Found 2 Pending Orders.

Expected Output 预期产量

Creating Orders... Expensive Operation...
Found 2 Pending Orders.
Removing Order...
Found 1 Pending Orders.

I am expecting that the Order being Fulfilled gets evicted from the "pendingOrders" cache. 我期望正在执行的订单从“ pendingOrders”缓存中被逐出。 But this doesn't appear to be happening. 但这似乎没有发生。 Thoughts? 有什么想法吗?

This is correct behaviour. 这是正确的行为。

@Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        List<Order> orders = orderService.getPendingOrders();
        System.out.println("Found " + orders.size() + " Pending Orders.");
        orderService.fulFillOrder(orders.stream().findFirst().get());
        orders = orderService.getPendingOrders();
        System.out.println("Found " + orders.size() + " Pending Orders.");
    }

I am expecting that the Order being Fulfilled gets evicted from the "pendingOrders" cache. 我期望正在执行的订单从“ pendingOrders”缓存中被逐出。 But this doesn't appear to be happening. 但这似乎没有发生。 Thoughts? 有什么想法吗?

This is because you are calling getPendingOrders() again to re-fill the cache with 2 Orders returned by this method. 这是因为您再次调用getPendingOrders()来用此方法返回的2个Order重新填充缓存。

You are calling orderService.getPendingOrders(); 您正在调用orderService.getPendingOrders(); again after fullfilling the order. 在完成订单后再次。 getPendingOrders() always returns 2 hard-coded Orders, and those are again put in cache as the getPendingOrders method is annotated with @Cacheable. getPendingOrders()始终返回2个硬编码的Order,并且随着getPendingOrders方法使用@Cacheable注释,这些订单将再次放入缓存中。 hence you are getting below again after Order is fulfilled. 因此,在完成订单后,您将再次跌至下方。

Found 2 Pending Orders. 找到2个待处理订单。

As per the javadocs 根据javadocs

@Cacheable Annotation indicating that the result of invoking a method (or all methods in a class) can be cached. @Cacheable注释,指示可以缓存调用方法(或类中的所有方法)的结果。

@CacheEvict Annotation indicating that a method (or all methods on a class) triggers a cache evict operation. @CacheEvict注释,指示某个方法(或类中的所有方法)触发缓存逐出操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM