In this project i am going to show a example how to use the Caching in Spring and generally improve the performance of our system.
Technologies used in the project:
- Java
- Springboot
- SpringData JPA
- Spring Cache
- Lombok
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
@SpringBootApplication
@EnableCaching
public class SpringBootCacheExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootCacheExampleApplication.class, args);
}
}
for that we need to use some @Annotations
These are:
@Cacheable
- to cache the result of the method@CacheEvict
- to evict the cache@Caching
- to group the @Cacheable and @CacheEvict annotations
@Service
public class UserServiceImpl implements UserService {
public static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
@Autowired
private UserRepository repository;
@Override
@CacheEvict(value = "users", allEntries = true)
public User save(User user) {
logger.info("Saving user: {}", user.getName());
return repository.save(user);
}
@Override
@Caching(evict = {
@CacheEvict(value = "users", allEntries = true),
@CacheEvict(value = "user", key = "#user.id")
})
public User update(Long id, User user) {
User userToUpdate = repository.findById(id).get();
userToUpdate.setName(user.getName());
userToUpdate.setEmail(user.getEmail());
logger.info("Updating user: {}", userToUpdate.getName());
return repository.save(userToUpdate);
}
@Override
@Cacheable(value = "users")
public List<User> findAll() {
logger.info("Finding all users");
return repository.findAll();
}
@Override
@Cacheable(value = "user", key = "#id", unless = "#result == null")
public User findById(Long id) {
logger.info("Finding user by id: {}", id);
return repository.findById(id).orElse(null);
}
@Override
@Caching(evict = {
@CacheEvict(value = "users", allEntries = true),
@CacheEvict(value = "user", key = "#id")
})
public void delete(Long id) {
logger.info("Deleting user by id: {}", id);
repository.deleteById(id);
}
}
mvn clean install
mvn spring-boot:run
GET localhost:8080/users to get all users
GET localhost:8080/users/1 to get user by id
PUT localhost:8080/users/1 to update user by id
POST localhost:8080/users to save user
DELETE localhost:8080/users/1 to delete user by id
For the first request if nothing is cached we have the following logs:
curl -X GET localhost:8080/users
LOGS:
INFO 1034 --- [nio-8080-exec-2] c.l.s.service.impl.UserServiceImpl : Finding all users
For the second request if something is cached we don't have any logs:
curl -X GET localhost:8080/users
LOGS:
But if we delete some user we have the following logs:
curl -X DELETE localhost:8080/users/1
LOGS:
INFO 1034 --- [nio-8080-exec-8] c.l.s.service.impl.UserServiceImpl : Deleting user by id: 1
Then will be deleted the cache for the user with id 1 and for the list of users.
And if we try to list the users again we have the following logs:
curl -X GET localhost:8080/users
LOGS:
INFO 1034 --- [nio-8080-exec-2] c.l.s.service.impl.UserServiceImpl : Finding all users