SHILPA
SHILPA

Reputation: 77

How to use the data stored in cache for another function in springboot

I have created a sample spring boot application which have a class "CacheManagement "where I have a function "getAllValue" which return the a customer object whose values I need to cache. This class also have a function checkCache which uses the data from cache. How Can I implement this. Somebody please help me on this. I am providing the class I have written.PFB the class

@Service
public class CacheManagement {
    
    @Cacheable(value = "service",key = "list")
    public Customer getAllValue(){
        Customer customer = new Customer();
        System.out.println("Inside cache");
        customer.setId("1");
        customer.setName("Shilpa");
        return customer;
    }
    
    public String checkCache() {
    Customer cus = getAllValue();
    System.out.println(cus.toString());
    return "1";
    
    }

}

PFB the main class:

@SpringBootApplication
public class DemoApplication implements CommandLineRunner{

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
    @Override
    public void run(String... arg0) {
        CacheManagement cacheService = new CacheManagement();
        cacheService.getAllValue();
        cacheService.checkCache();
                
        
        
    }
}

According to my need the sysout statement should only print once right? But my issue is it is printing twice .Means the getAllValue() call from checkCache() method is calling the function itself not fetching data from cache. Please help me to resolve this issue.

Upvotes: 0

Views: 1894

Answers (1)

R.G
R.G

Reputation: 7131

There are multiple issues with your code.

  1. CacheManagement cacheService = new CacheManagement(); creates an instance which is not a Spring container managed bean. The Spring magic will not work here . You should get a Spring container managed bean of cacheManagement for all your Spring framework support to kickin.
@SpringBootApplication
@EnableCaching
public class DemoApplication implements CommandLineRunner {
    @Autowired
    CacheManagement cacheService;

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Override
    public void run(String... arg0) {
        cacheService.getAllValue();
        cacheService.checkCache();
    }
}

2.Assuming you have enabled caching using @EnableCaching ( Refer here )

@SpringBootApplication
@EnableCaching
public class DemoApplication implements CommandLineRunner{
...
}

The Spring Caching works with the help of Spring AOP and Spring AOP works on proxies. Calling getAllValue() from within a method of the same class ( here checkCache()) is called a self-invocation. Spring AOP will not be able to advice the method call in this case , as it will not go through the proxy and hence the caching logic fails to work.

To understand this concept in detail , do refer the official spring reference documentation : Understanding AOP Proxies . Read through the section starting with The key thing to understand here is that the client code inside the main(..)

The resolution to your issue is to make sure the checkValue() call goes through the proxy so that the cached result is returned. Since you need the method (checkValue()) as part of the same bean , a self reference , will do it.

You must read through the official documentation on the same topic though to understand the implications. Section starting with As of 4.3, @Autowired also considers self references for injection ..

Following code should fix the issue for you

@Service
public class CacheManagement {

    @Autowired
    CacheManagement self;
    
    @Cacheable(value = "service",key = "list")
    public Customer getAllValue(){
        Customer customer = new Customer();
        System.out.println("Inside cache");
        customer.setId("1");
        customer.setName("Shilpa");
        return customer;
    }
    
    public String checkCache() {
    Customer cus = self.getAllValue();
    System.out.println(cus.toString());
    return "1";
    
    }

}

Read more on caching here

Upvotes: 1

Related Questions