Best Practices for Implementing Spring Caching?

103 Views Asked by At

Right now, my app is organized like this:

  • Controller Layer: Handles user requests.
  • Business Service Layer: Manages data, including caching.
  • Repository Layer: Deals with data storage.

Code Example:

// Controller Layer
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/users/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.getUserById(id);
    }
}

// Business Service Layer
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    @Cacheable(value = "users", key = "#id")
    public User getUserById(Long id) {

        // some business checks
        return userRepository.findById(id).orElse(null);
    }
}

// Repository Layer
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

I want to introduce application level caching :

  • Controller Layer: No change.
  • Business Service Layer: Still handles data but now using cache manager.
  • Cached Service Layer: New layer for handling cached data.
  • Repository Layer: Remains the same.

Code Example:

// Controller Layer
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/users/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.getUserById(id);
    }
}

// Business Service Layer
@Service
public class UserService {
    @Autowired
    private CachedUserService cachedUserService;

    public User getUserById(Long id) {
            // some Business Logic
        return cachedUserService.getUserById(id);
    }
}

// Cached Service Layer
@Service
public class CachedUserService {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private CacheManager cacheManager;

    public User getUserById(Long id) {
        Cache cache = cacheManager.getCache("users");
        ValueWrapper result = cache.get(id);

        if (result != null) {
            return (User) result.get();
        } else {
            User user = userRepository.findById(id).orElse(null);
            cache.put(id, user);
            return user;
        }
    }
}

// Repository Layer
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

Is this a good way to update my app's structure, or are there any potential problems or better approaches I should consider? Your advice would be really helpful. Thanks!

0

There are 0 best solutions below