복붙노트

[SPRING] Spring 캐시 @ 동일한 클래스에서 호출 할 때 캐시 가능한 메소드가 무시됩니다.

SPRING

Spring 캐시 @ 동일한 클래스에서 호출 할 때 캐시 가능한 메소드가 무시됩니다.

동일한 클래스 내에서 @Cacheable 메서드를 호출하려고합니다.

@Cacheable(value = "defaultCache", key = "#id")
public Person findPerson(int id) {
   return getSession().getPerson(id);
} 

public List<Person> findPersons(int[] ids) {
   List<Person> list = new ArrayList<Person>();
   for (int id : ids) {
      list.add(findPerson(id));
   }
   return list;
}

findPersons의 결과도 캐싱되기를 기대하지만 @Cacheable 주석은 무시되고 findPerson 메서드는 매번 실행됩니다.

내가 여기서 뭔가 잘못하고 있는거야, 아니면이게 의도 된거야?

해결법

  1. ==============================

    1.이것은 캐싱, 트랜잭션 관련 기능을 처리하기 위해 프록시가 생성되는 방식 때문입니다. 이것은 Spring이 처리하는 방법에 대한 훌륭한 참고서입니다 - 트랜잭션, 캐싱 및 AOP : Spring에서의 프록시 사용 이해

    이것은 캐싱, 트랜잭션 관련 기능을 처리하기 위해 프록시가 생성되는 방식 때문입니다. 이것은 Spring이 처리하는 방법에 대한 훌륭한 참고서입니다 - 트랜잭션, 캐싱 및 AOP : Spring에서의 프록시 사용 이해

    요컨대, 자기 호출은 동적 프록시를 우회하고 동적 프록시 로직의 일부인 캐싱, 트랜잭션 등의 교차 절단 문제도 우회합니다.

    수정 사항은 AspectJ 컴파일 시간 또는로드 시간 짜기를 사용하는 것이다.

  2. ==============================

    2.다음은 동일한 클래스 내에서 메소드 호출의 사용량이 극히 적은 소규모 프로젝트에서 수행하는 작업입니다. 동료에게 스트레스를 줄 수 있으므로 코드 내 문서가 강력하게 권고됩니다. 그러나 테스트하기 쉽고, 간단하고, 신속하게 달성 할 수 있으며, 전체 AspectJ 계측 장비를 절약 할 수 있습니다. 그러나, 더 많은 사용량을 위해 나는 AspectJ 솔루션에 대한 충고를 원한다.

    다음은 동일한 클래스 내에서 메소드 호출의 사용량이 극히 적은 소규모 프로젝트에서 수행하는 작업입니다. 동료에게 스트레스를 줄 수 있으므로 코드 내 문서가 강력하게 권고됩니다. 그러나 테스트하기 쉽고, 간단하고, 신속하게 달성 할 수 있으며, 전체 AspectJ 계측 장비를 절약 할 수 있습니다. 그러나, 더 많은 사용량을 위해 나는 AspectJ 솔루션에 대한 충고를 원한다.

    @Service
    @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
    class PersonDao {
    
        private final PersonDao _personDao;
    
        @Autowired
        public PersonDao(PersonDao personDao) {
            _personDao = personDao;
        }
    
        @Cacheable(value = "defaultCache", key = "#id")
        public Person findPerson(int id) {
            return getSession().getPerson(id);
        }
    
        public List<Person> findPersons(int[] ids) {
            List<Person> list = new ArrayList<Person>();
            for (int id : ids) {
                list.add(_personDao.findPerson(id));
            }
            return list;
        }
    }
    
  3. ==============================

    3.Grails Spring Cache 플러그인을 사용하는 모든 사용자는 문서에서 해결 방법을 설명합니다. 나는이 문제를 grails 응용 프로그램에서 가졌지 만 불행히도 Grails에서는 사용 가능한 대답이 사용 불가능한 것 같습니다. 해결책은 못생긴, IMHO,하지만 작동합니다.

    Grails Spring Cache 플러그인을 사용하는 모든 사용자는 문서에서 해결 방법을 설명합니다. 나는이 문제를 grails 응용 프로그램에서 가졌지 만 불행히도 Grails에서는 사용 가능한 대답이 사용 불가능한 것 같습니다. 해결책은 못생긴, IMHO,하지만 작동합니다.

    예제 코드는 다음과 같이 잘 보여줍니다.

    class ExampleService {
        def grailsApplication
    
        def nonCachedMethod() {
            grailsApplication.mainContext.exampleService.cachedMethod()
        }
    
        @Cacheable('cachedMethodCache')
        def cachedMethod() {
            // do some expensive stuff
        }
    }
    

    단순히 exampleService.cachedMethod ()를 자신의 서비스 및 메소드로 대체하십시오.

  4. from https://stackoverflow.com/questions/12115996/spring-cache-cacheable-method-ignored-when-called-from-within-the-same-class by cc-by-sa and MIT license