개발 일지/주간 개발 일지

[09월 1주차] 캐시와 스프링 AOP, @Cacheable

계란💕 2023. 9. 15. 15:36

캐시(cache)

  • 캐시란? 
  • 반복적으로 요청되는 데이터를 임시로 메모리 저장했다가 다음 요청이 왔을 때, DB에 접근하지 않고 메모리에서 읽어오는 것을 말한다. 
  • 최초 요청 시에만 DB 에 접근하므로 시간적으로 효율적이고 성능도 좋아진다.

 


Spring 캐시 사용 방법 - @CacheEvict, @Cacheable

 

<hide/>
@Cacheable(cacheNames = "model", key = "#modelNm", unless = "#result == null")
public ModelVo getModel(String modelNm) {
	// 모델 조회
    return model;
}

@CacheEvict(cacheNames = "model", key = "#modelNm")
public void removeModel(String modelNm) {
	// 별다른 로직 필요없음
}

 

  • 서비스 클래스의 모델을 조회하는 어떤 메서드에 대해 캐시를 적용하려 한다. 
  • @Cacheable(cachename = "model", key="#modelNm")
  • cachename: 캐시 네임이다. 캐시된 데이터의 소속 그룹을 구분하기 위한 그룹명이라고 이해했다. 
  • key: 해당 캐시 그룹 안에서 key 값을 통해 캐싱한다. (메서드 안의 매개 변수명과 key가 같게 만든다.)
    • void getModel(String modelNm)
    • ex) model 이라는 캐시 그룹 안에서 key로 설정한 modelNm을 통해 데이터를 조회하고 저장할 수 있다. 
  • @CacheEvict(cachename = "model", key = "#modelNm", allEntries= true/false): 캐시 제거
    • 캐시하고자 하는 데이터의 값이 달라질 때 캐시를 제거하고 일정한 주기로 캐시를 제거해야 정상적으로 데이터를 조회할 수 있다. 
    • key 에 해당하는 데이터만 제거한다.
    • 캐시에서 특정 데이터만 지우는 게 아니라 모든 값을 모두 지우려면 allEntries = true 속성을 추가한다.  이 경우에 key를 넣을 필요없다. 

 

  • 스프링에서 캐시 관련 위 애너테이션을 쓰기 위해서는 cache 설정 클래스를 만들어야한다. 하지만, 매인 클래스에   @EnableCaching을 붙이면 캐시 설정 클래스가 필요없다. 
  • 보통 메서드에 애너테이션을 붙여서 캐시에 데이터가 없을 경우, 로직을 실행한 다음 캐시에 데이터를 추가하고 캐시에 데이터가 있으면 캐시에 데이터를 반환한다. 
  • @Cacheable(key ="", value="")

 

 

Note) 중요!

  • 캐싱은 스프링 AOP와 관련이 있다. 
  • 주의) @Cacheable 이 붙은 메서드는 반드시 다른 클래스를 호출해야만 캐시를 적용할 수 있다. 
    • 캐싱은 AOP 프록시를 통과할 때 적용된다. 따라서, 같은 클래스 내에서 호출하면  AOP 프록시를 우회하기 때문에 캐시가 동작하지 않는다.

 

https://ifuwanna.tistory.com/202


 

AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)

  • AOP란 어떤 핵심적인 비즈니스 로직과 공통 모듈을 구분하고 핵심 로직에 영향을 주지 않으면서 공통 모듈을 효과적으로 끼워넣는 프로그래밍 방법을 말한다. 
  • ex) 로그 처리, 예외처리, 보안 인증 트랜잭션 처리, 캐싱 등 공통화할 수 있는 처리를 aspect 하나의 단위로 묶어서 어떤 객체가 본질적인 역할만 하도록 하는 기능이다. 

 

 스프링 AOP 공식 문서 

https://docs.spring.io/spring-framework/docs/2.0.x/reference/aop.html

 

 


AOP 의 구성요소

  • AOP는 다음과 같이 구성된다. 

 

  • Aspect 
    • 여러 객체를 가로지르는 관심사의 모듈화이다. 일반 클래스 또는 @AspectJ 사용해서 구현된다. 
    • 트랜잭션 관리는 좋은 예시이다. 
  • 대상 객체(Target Object)
    • 실제 비지니스 로직을 포함하는 객체이다. 
    • 프록시는 대상 객체를 감싸서 AOP를 적용한다. 
    • 하나 이상의 Aspect로부터 advice를 받는 객체이다. 
    • 항상 프록시 객체이다. 
  • 프록시 객체(Proxy Object, AOP proxy): 대상 객체를 감싸는 중간 객체이다.
    • 대상 객체에 대한 호출을 가로채고 필요한 어드바이스를 실행한 다음 대상 객체의 메서드를 호출한다. 
    • AOP프레임워크에서 생성된 객체이다. ex) JDK dynamic proxy 또는 CGLIB proxy가 이에 해당한다. 
  • 조인 포인트(Join Point): 특정 이벤트 실행되는 시점을 나타낸다. 
  • 어드바이스(advice): AOP에서 실제 수행하려는 작업을 정의한 것이다. 조인 포인트 주변에 끼워넣어 동작시킨다. 
    • 대상 객체의 메서드 호출 전, 후 또는 예외 발생 시에 실행될 수 있다.
    • 주로 로깅, 트랜잭션 관리, 예외 처리 등과 같은 공통적인 관심 사항을 구현한다.
    • 인 포인트 안에서 실행되는 부분이다.  
      • 어드바이스 종류
        • before advice
        • after returning advice: 대상 메서드가 실행된 뒤에 무언가를 실행한다 
        • after throwing advice
        • after (finally) advice 
        • around advice: 가장 흔하게 쓰이는 어드바이스이다.
  • 포인트컷(Pointcut): 어떤 조인 포인트를 선택할지 정의하는데 사용된다. 이는 aspect에서 어떤 메서드나 클래스에 언제 적용할 것인지를 결정하는데 도움을 준다.   
    • 어드바이스가 실행되는 진입점을 의미
    • Join Point 의 집합을 정의한다. 
    • 어떤 조인 포인트를 선택할지 말지 결정한다. 
  • 위빙(weaving): 스프링은 프록시를 생성하고 aspect를 적용하는 과정을 위빙이라고 한다.  이 과정은 컴파일 시점, 클래스 로딩 시점, 런타임 시점 중 하나에서 수행될 수 있다. 

 

  Ex)  AOP를 적용한 캐시 업데이트

  • 캐시 대상 메서드의 반환값을 사용해서 캐시를 업데이트 해야하는 경우, 
  • after returning advice가 around advice보다 적합하다. 
  • after returning advice: 사용하면 메서드가 정상적으로 완료된 후에 실행되는데 이 때의 반환값을 업데이트에 활용 가능하다. 
  • around advice는 메서드 호출을 둘러싸서 메서드 실행 이전이후에 사용자 정의 동작을 수행 가능하다. 
  • 둘다 쓸 수 있는 경우에는 간단하게 after returning advice를 추천.

 


찾아보기

  • 필터 인터셉터 AOP 차이점

 

참고

https://mangkyu.tistory.com/179

https://oranthy.tistory.com/339

 

읽어보기

https://scshim.tistory.com/429