związanej zatwierdzenia w ramach wiosennej https://github.com/spring-projects/spring-framework/commit/5aefcc802ef05abc51bbfbeb4a78b3032ff9eee3Wiosna cache używając @Cacheable podczas @PostConstruct nie działa
inicjalizacji jest ustawiony na późniejszym etapie z afterPropertiesSet() do afterSingletonsInstantiated()
W skrócie: Zapobiega to pracy bufora podczas używania w przypadku użycia @PostConstruct.
Dłuższa wersja: Zapobiega to przypadek użycia gdzie byś
tworzenia serviceB z @Cacheable na MethodB
tworzenia serviceA z @PostConstruct wywołującego serviceB.methodB
@Component public class ServiceA{ @Autowired private ServiceB serviceB; @PostConstruct public void init() { List<String> list = serviceB.loadSomething(); }
Powoduje to, że org.springframework.cache.interceptor.CacheAspectSupport nie jest teraz inicjowany i nie buforuje wyniku.
protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
// check whether aspect is enabled
// to cope with cases where the AJ is pulled in automatically
if (this.initialized) {
//>>>>>>>>>>>> NOT Being called
Class<?> targetClass = getTargetClass(target);
Collection<CacheOperation> operations = getCacheOperationSource().getCacheOperations(method, targetClass);
if (!CollectionUtils.isEmpty(operations)) {
return execute(invoker, new CacheOperationContexts(operations, method, args, target, targetClass));
}
}
//>>>>>>>>>>>> Being called
return invoker.invoke();
}
Moje obejście jest ręcznie wywołać metodę inicjalizacji:
@Configuration
public class SomeConfigClass{
@Inject
private CacheInterceptor cacheInterceptor;
@PostConstruct
public void init() {
cacheInterceptor.afterSingletonsInstantiated();
}
To oczywiście rozwiązuje mój problem, ale to ma skutki uboczne innych, które po prostu są nazywane 2 razy (1 instrukcja i 1 przez ramy zgodnie z przeznaczeniem)
Moje pytanie brzmi: „Czy to jest bezpieczne obejście zrobić jak początkowa commiter wydawało się, że problem z tylko przy użyciu afterPropertiesSet()”
Opcja '@ PostConstruct' daje żadnych gwarancji, że serwery proxy zostały już utworzone (czyli z tego samego powodu, dlaczego' @ Transactional' nie działa dla 'Metody @ PostConstruct'.Metodę '@ PostConstruct' wywołuje się zaraz po skonstruowaniu i po wstrzyknięciu zależności, ale prawie zawsze przed punktem, w którym zostały utworzone proxy. Dlaczego potrzebujesz go w metodzie '@ PostConstruct'? Ogólnie rzecz biorąc, 'ApplicationListener' lepiej implementuje interfejs 'SmartInitializingSingleton' zamiast' @ PostConstruct'. –
Dziękuję za odpowiedź. Używamy postkonstruktu do inicjowania komponentu bean z wartościami pobranymi z innej usługi (która ma @Cacheable na swoich metodach) Oczekiwaliśmy, że wartości te zostaną zbuforowane nawet przy użyciu postkonstrukcji. Jeśli tak nie jest, to dokument java byłby korzystny dla środowiska, ponieważ inni deweloperzy mogą nie być tego świadomi. Zamiast tego spróbuję SmartInitializingSingleton. Dzięki! – user2966436
Zostało to wyjaśnione w [podręczniku] (http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-factory-lifecycle-default-init-destroy-methods) przeczytaj ostatni akapit tej sekcji. –