Spring Book – Chapter 10 – Caching

Important Cache Annotations

Spring Framework uses several annotations to manage your caches in an easy way in your application. The important ones are:

  • @Cacheable
  • @CacheEvict
  • @CachePut
  • @Caching

@Cacheable

You can place the @Cacheable annotation on a method, on an interface, or a public method on a class. However, as explained earlier, the mere presence of the @Cacheable annotation is not enough to activate the caching behavior in your Spring application. The @Cacheable annotation is simply a metadata that can be consumed by some runtime infrastructure that is @Cacheable-aware and that can use the metadata to configure the appropriate beans with caching behavior. As discussed in earlier section of this same chapter, the  element in the Spring XML configuration switches on the caching behavior.

Spring recommends that you only annotate methods of concrete classes with the @Cacheable annotation, as opposed to annotating methods of interfaces. You do have a provision to put @Cacheable annotation on an interface or an interface method, but this will only work if you are using interface-based proxies.

Moreover, when using proxies, you should apply the @Cacheable annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Cacheable annotation, no error is raised, but the annotated method does not exhibit the configured cacheable settings.

Another notable thing is that, only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual cache interception at runtime even if the invoked method is marked with @Cacheable.

@Cacheable Settings

The @Cacheable annotation is a metadata that specifies that a method must have cache semantics. The various properties of the @Cacheable annotation are summarized as shown in Table 10-1 below.

Table 10-1. @Cacheable settings (Attributes which can be used to control caching)

Element Name Element Type Description
value String[] Name(s) of the caches in which update needs to take place. It can be used for specifying target cache(s), matching the qualifier value (or the bean name(s)) of (a) specific bean definition. Mandatory element.
key String Spring Expression Language (SpEL) attribute, which can compute keys dynamically. The default value is “” and takes in all the method parameter names as keys.
condition String Spring Expression Language (SpEL) attribute, which can be used for conditioning the method cache.  The default value is “”, which means that the method will always be cached.

Complete example class using the major cache annotation provided by Spring framework is shown in the Listing 10-14. In this section I have used some code snippets for explaining the various elements in the cacheable annotation.

Listing 10-5. A simple usage of @Cacheable annotation

[java]public class CustomerRepository{

@Cacheable(“customer”)

public Customer getCustomer(String customerCode){

//….

}

}[/java]

In Listing 10-5, @Cacheable usage causes method argument to be used as the default keys in storing the method results in the cache. The method “getCustomer” is associated with the cache name “customer”. Each time this method is called, the cache is checked to see if the method has been executed earlier with the same attributes. If so, it returns from cache rather than going to the database. In most cases it is sufficient to declare only one cache but the annotation allows putting multiple cache names, as shown in Listing 10-6, which will then be used to store the cache’s key-value pairs.

Listing 10-6. Usage of @Cacheable annotation with mutiple cache names

[java]public class CustomerRepository{

@Cacheable(“customer”,”generic”)

public Customer getCustomer(String customerCode){

//….

}

}[/java]

In Listing 10-7, “condition” attribute in @Cacheable is used to check if the “customerCode” length is exactly equal to 30. If it satisfies the condition, the caching will be done. You can also calculate appropriate caching conditions on fly.

Listing 10-7. Usage of @Cacheable in which cache conditions are defined

[java]public class CustomerRepository{

@Cacheable(value=“customer”,condition=”#customerCode.length = 30”)

public Customer getCustomer(String customerCode){

//….

}

}[/java]

Listing 10-8, shows calculation the caching condition in which it is only cached if the day in which the method is called is not a weekend (on weekends, the load is less and performance might not be a concern).

Listing 10-8. Usage of @Cacheable in which the cache condition is calculated on the fly

[java]public class CustomerRepository{

@Cacheable(value=“customer”,condition=”!T(TimeUtils).isWeekend()”)

public Customer getCustomer(String customerCode){

//….

}

}[/java]

You have seen in the above sections, how @Cacheable annotation can be used to integrate cache easily into your application. But, we haven’t seen how this annotation helps us in doing thing in a easy manner. Listing 10-9 shows @Cacheable equivalence, that means, it shows what this annotation does it for you.

Listing 10-9. @Cacheable equivalance Java code

[java]import org.springframework.cache.Cache.ValueWrapper;

public class CustomerRepository{

@Inject

CacheManager cacheManager;//Use standard Java annotation @Inject for injection

public Customer getCustomer(String customerCode){

Cache cache = cacheManager.getCache(“customer”);

ValueWrapper mapValue = cache.get(customerCode);

if(mapValue != null){

return (Customer)mapValue.get();

}

//Do appropriate things to get the required customer

Customer customer = //get customer by whatever means

//…..

cache.put(customerCode, customer);

return customer;

}

}[/java]

Key Generation

Caches are essentially key-value stores and each invocation is translated into a suitable key value to access the cache. Spring uses simple key generation methodology using the following algorithm to generate the key for cache invocation:

  • If no method parameters are there, the key generator returns 0.
  • If only one parameter is present in the method, the key generator returns that instance.
  • If more the one parameter is present in the method, the key generator return a key computed from the hashes of all parameters.

Listing 10-10. Explicit way of defining keys for the caching using SpEL – Sample 1

[java]public class CustomerRepository{

@Cacheable(value=“customer”,key=”#customer.customerCode”)

public Customer getCustomer(Customer customer){

//….

}

}[/java]

Listing 10-11. Explicit way of defining keys for the caching using SpEL – Sample 2

[java]public class CustomerRepository{

@Cacheable(value=“customer”,key=”T(someType).hash(#customerCode)”)

public Customer getCustomer(String customerCode){

//….

}

}[/java]

If you would like to provide your own custom key generator, you need to implement the org.springframework.cache.KeyGenerator interface. Once done, you will have to configure the generator and the caching framework will use this new key generator for each method declaration which hasn’t specified its own key generation strategy.

Page Visitors: 10817

The following two tabs change content below.
Tomcy John

Tomcy John

Blogger & Author at javacodebook
He is an Enterprise Java Specialist holding a degree in Engineering (B-Tech) with over 10 years of experience in several industries. He's currently the Senior Technical Engineer at Emirates Group IT since 2005. Prior to this he has worked with Oracle Corporation and Ernst & Young. His main specialization is on various web technologies and acts as chief mentor and Principal Architect to facilitate incorporating Spring as Corporate Standard in the organization.

4 thoughts on “Spring Book – Chapter 10 – Caching

    1. I don’t know whether i should take your comment as positive or negative.. :). If it is positive, thank you. If it is negative, please let me know what i can improve on to make it positive.. 🙂

      Regards
      Tomcy John

  1. Hi,

    Is there a PDF version of this article, or at least a Web version somewhere else? This Website is really bad (full of ads) and the code samples are incomplete.

    Thanks,
    Lukasz

    1. Hi Lukasz,

      I plan to have a ad free version of the entire book. For that, though, i plan to distribute with a small charge. By end of October I plan to release using “Gumroad”. If you are still interested, with a small fee you can download and enjoy an ad free version of the book.

      Regards
      Tomcy John

Leave a Reply

Your email address will not be published. Required fields are marked *