Spring @CacheEvict行为

时间:2017-10-04 05:55:07

标签: spring caching spring-boot

我试图了解Spring Cache Abstraction中@CacheEvict的行为。这是我的示例应用程序

的pom.xml

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

应用

@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.");
    }
}

模型

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
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...");
    }
}

实际输出

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

预期输出

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

我期待被执行的订单从&#34; pendingOrders&#34;中被驱逐出去。缓存。但这似乎并没有发生。想法?

1 个答案:

答案 0 :(得分:0)

这是正确的行为。

@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.");
    }
  

我期待被执行的命令被驱逐出境   “pendingOrders”缓存。但这似乎并没有发生。   想法?

这是因为您再次调用getPendingOrders()以使用此方法返回的2个Orders重新填充缓存。

您正在调用orderService.getPendingOrders();完成订单后再次。 getPendingOrders()始终返回2个硬编码的订单,并且这些订单再次放入缓存中,因为getPendingOrders方法使用@Cacheable进行注释。 因此,在订单履行完毕后,您将再次降到最低点。

  

找到2个待处理的订单。

根据javadocs

<强> @Cacheable 注释表示可以缓存调用方法(或类中的所有方法)的结果。

<强> @CacheEvict 注释指示方法(或类上的所有方法)触发缓存逐出操作。