anik
anik

Reputation: 155

How to access value cached using spring @cacheable in other controllers?

I have a frequently accessed but bulky value - valueA which is obtained by a method - methodA of rest controller - ControllerA. So I have cached this value using @Cacheable annotation as follows.

    @CacheConfig(cacheNames={"abc_cache"})
    public class ControllerA
{

    @Cacheable
    @RequestMapping(value = "/value/" , method=RequestMethod.GET)
    public ResponseEntity<Value> fetchValue()
    {
       // some logic
       return new ResponseEntity<Value>(value, HttpStatus.OK);
    }
}

I want to access this value in another method - methodB of another controller - controllerB. How can I access this value?

Upvotes: 3

Views: 4501

Answers (2)

Evgeni Dimitrov
Evgeni Dimitrov

Reputation: 22506

You can have some other class/bean to supply that value. Then you can inject that bean in all the controllers that you want.

Something like this:

@Component
public class MyValueService {
    @Cacheable
    public Value getValue() {
        return ...;
    }
}

and then in the controllers

public class ControllerA
{
    @Autowired
    private MyValueService valServ;

    @RequestMapping(value = "/value/" , method=RequestMethod.GET)
    public ResponseEntity<Value> fetchValue()
    {
       return new ResponseEntity<Value>(valServ.getValue(), HttpStatus.OK);
    }
}

Are you aware of the Controller -> Service -> Repository pattern?

Basically:

Controllers are the web layer. They handle http requests. They use Services.

Services are responsible for the business logic of the application. They use Repositories.

Repositories are responsible for the data access - databases access, read/write from the file system, etc.

You should structure your application that way.

In general I would use caching on the Repository layer. Usually the bottle neck are the I/O operations (read/write to the file system, DB call, calling external service over the network) and that are the things that you want to cache if the possible.

Upvotes: 4

dylaniato
dylaniato

Reputation: 516

I think you should just encapsulate your cacheable logic into a method in another class and then just call it from both controllers.

So

public class ControllerA
{

    @Resource
    private Service service;

    @RequestMapping(value = "/value/" , method=RequestMethod.GET)
    public ResponseEntity<Value> fetchValue()
    {
       // some logic
       Object v = service.cachedMethod();
       return new ResponseEntity<Object>(v, HttpStatus.OK);
    }
}

and

@Component
public class Service {

    @Cacheable
    public Object cachedMethod() {... }

}

Upvotes: 2

Related Questions