본문 바로가기
Develop/Spring+JPA

[Spring] 스프링 캐시 간단하게 사용해보기

by 연로그 2023. 5. 31.
반응형

목차

1. 스프링의 캐싱 방법

2. 사전 준비

3. 예제 코드


 


1. 스프링의 캐싱 방법

 

캐싱

  • 자주 사용하는 데이터를 어딘가 임시로 저장하고, 빠르게 꺼내 쓰기 위해 사용할 수 있게 하는 프로세스
  • 서버의 부담을 줄여 성능을 높이기 위해 사용하기도 함
  • ex: DB에서 조회하는게 굉장히 오래 걸리는 데이터를 캐싱해두면, 다음에 조회할 때 DB의 조회 결과를 기다리지 않고 캐싱 영역에서 빠르게 가져다 쓸 수 있음

 

스프링의 캐싱

  • @Cacheable, @CacheEvict 같은 어노테이션을 통해 AOP 기반으로 동작
  • 이를 위해서는 @EnableCaching 설정이 필수

 

 


2.  사전 준비

이 글에서는 Redis를 이용해 예제 코드를 작성하기 때문에 사전 준비가 필요하다.

별도의 Redis를 사용하지 않는 경우에는 생략해도 된다.

 

2-1. 로컬에 Redis 설치

🔗 링크로 대체

 

GitHub - yeon-06/practice-redis

Contribute to yeon-06/practice-redis development by creating an account on GitHub.

github.com

 

2-2. Redis 설정

편의를 위해 Spring Data Redis를 이용했다. Gradle의 경우, build.gradle에 아래 설정을 추가하면 된다.

implementation 'org.springframework.boot:spring-boot-starter-data-redis-reactive'

 

Redis 사용을 위한 설정 파일을 만든다. RedisCacheConfiguration을 여러개 설정할 수도 있고, 더 다양한 옵션을 설정할 수도 있지만 자세한건 생략한다.

@Configuration
public class CacheConfiguration {

    @Bean
    public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer() {
        return builder -> builder.withCacheConfiguration("customerCache", customerCacheConfiguration());
    }

    private RedisCacheConfiguration customerCacheConfiguration() {
        return RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(1)); // 캐싱 시간을 1분으로 설정한다.
    }
}

 

 


3. 예제 코드

3-1. @EnableCaching 추가

메인 클래스에 @EnableCaching을 추가해주었다.

@EnableCaching
@SpringBootApplication
public class RedisApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisApplication.class, args);
    }
}

 

@EnableCaching
* public 메서드에 캐싱 어노테이션이 있는지 모든 Spring bean을 검사하는 post-processor를 동작시킨다.
* 캐싱 어노테이션이 발견되면 메서드 호출을 가로채고, 캐싱 동작을 처리하기 위한 프록시가 자동으로 생성된다.

 

3-2. 캐싱할 객체 생성

고객 정보를 캐싱한다고 가정한다. Customer와 CustomerRepository를 만들었다.

public class Customer {
    private Long id;
    private String name;
    private String email;
    private LocalDate birthday;

    // 생성자, getter, setter, ...
}

 

(DB와 연동하기 귀찮은 관계로) Map을 이용해 Repository를 구현했다.

@Repository
public class CustomerRepository {

    private Long id = 1L;
    private final Map<Long, Customer> customers = new HashMap<>();

    public void save(Customer customer) {
        customer.setId(id);
        customers.put(id, customer);
        id++;
	}

    public Customer getById(Long id) {
        return customers.get(id);
    }
    
    public void deleteById(Long id) {
        customers.remove(id);
    }
    
    public void updateEmail(Long id, String email) {
        Customer customer = getById(id);
        customer.setEmail(email);
        return customer;
    }
}

 

3-3. @Cacheable 예제

이제 캐싱할 준비가 모두 끝났다. 캐싱하고 싶은 데이터를 반환하는 메서드에 @Cacheable을 붙이기만 하면 된다. 만약 이미 캐싱된 데이터를 요청하는 경우, 메서드 호출을 생략하고 캐시에서 결과를 가져온다.

@Service
public class CacheService {

    private final CustomerRepository customerRepository;

    public CacheService(CustomerRepository customerRepository) {
        this.customerRepository = customerRepository;
    }

    @Cacheable(key = "#id", value = "customerCache")
    public Customer findCustomerById(Long id) {
        return customerRepository.getById(id);
    }
}

 

@Cacheable 주요 속성

속성 설명
value 캐시로 사용될 이름
key 캐시의 key 
condition 캐시를 저장할 조건
unless 캐시를 저장하지 않을 조건
cacheManger 사용할 캐시 매니저의 이름 지정
cacheResolver 사용할 캐시 리졸버의 이름 지정

 

3-4. @CacheEvict 예제

@CacheEvict는 캐싱된 데이터를 삭제하기 위해 사용한다. 설정에서 직접 캐싱 시간을 지정할 수도 있지만, @CacheEvict를 이용하면 메서드를 호출할 때 직접 제거해줄 수 있다.

@CacheEvict(key = "#id", value = "customerCache")
public void deleteCustomerById(Long id) {
    customerRepository.deleteById(id);
}

 

@CacheEvict 주요 속성

속성 설명
value 캐시 이름
key 캐시의 key 
condition 캐시를 삭제할 조건
allEntries 캐시 전체 삭제 여부
beforeInvocation 메서드 실행 전 캐시 삭제 여부
cacheManger 사용할 캐시 매니저의 이름 지정

 

3-5. @CachePut 예제

@Cacheable은 이미 캐싱된 데이터가 존재하면 메서드를 호출하지 않았다. @CachePut은 메서드는 항상 실행되고 결과는 캐시된다. (캐시 내용을 업데이트 한다.)

@CachePut(key = "#id", value = "customerCache")
public Customer updateCustomerById(Long id, String email) {
    return customerRepository.updateEmail(id, email);
}

 

@CachePut 주요 속성

속성 설명
value 캐시 이름
key 캐시의 key 
condition 캐시를 저장할 조건
unless 캐시를 저장하지 않을 조건
cacheManger 사용할 캐시 매니저의 이름 지정

 

3-6. 추가 예제

여러 캐싱 어노테이션을 사용하고 싶다면 @Caching을 이용해야 한다. 

@Caching(evict = { 
    @CacheEvict("emails"), 
    @CacheEvict(value="customerCache", key="#customer.email") 
})
public String getEmail(Customer customer) {...}

 


참고

반응형