programing

스프링 캐시 @Cacheable 메서드가 같은 클래스 내에서 호출될 때 무시됨

subpage 2023. 10. 11. 20:44
반응형

스프링 캐시 @Cacheable 메서드가 같은 클래스 내에서 호출될 때 무시됨

전화하려고 하는데요.@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메소드는 매번 실행되었습니다.

제가 여기서 뭔가 잘못하고 있는 건가요, 아니면 의도된 건가요?

이것은 봄에 캐싱, 트랜잭션 관련 기능을 처리하기 위해 프록시를 만드는 방식 때문입니다.이것은 Spring이 처리하는 방법에 대한 매우 좋은 참고 자료입니다 - 트랜잭션, 캐싱AOP: Spring의 프록시 사용 이해

즉, 셀프 호출은 동적 프록시를 우회하고 동적 프록시 로직의 일부인 캐싱, 트랜잭션 등과 같은 교차 문제도 우회합니다.

해결책은 Aspec J 컴파일 타임 또는 로드 타임 위빙을 사용하는 것입니다.

여기에 제가 같은 클래스 내에서 메소드 호출의 한계적인 사용만을 가진 작은 프로젝트에 대해 하는 일이 있습니다.인코드 문서는 동료에게 이상하게 보일 수 있으므로 강력하게 권장됩니다.하지만 테스트가 쉽고 간단하며, 신속하게 달성할 수 있으며, 완전한 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;
    }
}

Grails Spring Cache 플러그인을 사용하는 모든 사용자의 경우 해결 방법이 설명서에 설명되어 있습니다.grails 앱에서 이 문제가 발생했지만 안타깝게도 수락된 답변은 grails에서 사용할 수 없는 것 같습니다.해결책은 추하지만, 효과는 있습니다, 임호.

예제 코드는 이를 잘 보여줍니다.

class ExampleService {
    def grailsApplication

    def nonCachedMethod() {
        grailsApplication.mainContext.exampleService.cachedMethod()
    }

    @Cacheable('cachedMethodCache')
    def cachedMethod() {
        // do some expensive stuff
    }
}

예제 Service.catchedMethod()를 사용자 고유의 서비스 및 메서드로 교체하기만 하면 됩니다.

언급URL : https://stackoverflow.com/questions/12115996/spring-cache-cacheable-method-ignored-when-called-from-within-the-same-class

반응형