nicht auf den im Frühjahr Rahmen commit Zusammenhang https://github.com/spring-projects/spring-framework/commit/5aefcc802ef05abc51bbfbeb4a78b3032ff9eee3Feder Cache @Cacheable während @PostConstruct Verwendung funktioniert
die Initialisierung von afterPropertiesSet zu einem späteren Zeitpunkt gesetzt() zu afterSingletonsInstantiated()
In Kürze: Dies verhindert, dass das Caching funktioniert, wenn es in einem @ PostConstruct-Anwendungsfall verwendet wird.
Längere Version: Dies verhindert die Verwendung Fall, in dem Sie sich
erstellen serviceB mit @Cacheable auf einem methodeB
erstellen serviceA mit @PostConstruct Aufruf serviceB.methodB
@Component public class ServiceA{ @Autowired private ServiceB serviceB; @PostConstruct public void init() { List<String> list = serviceB.loadSomething(); }
Dies führt dazu, dass org.springframework.cache.interceptor.CacheAspectSupport jetzt nicht initialisiert wird und das Ergebnis nicht zwischengespeichert wird.
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();
}
Meine Abhilfe ist, manuell die Initialisierung Methode aufzurufen:
@Configuration
public class SomeConfigClass{
@Inject
private CacheInterceptor cacheInterceptor;
@PostConstruct
public void init() {
cacheInterceptor.afterSingletonsInstantiated();
}
Das ist natürlich mein Problem behebt, aber hat es Nebenwirkungen andere, die nur 2-mal aufgerufen wird (1 Handbuch und 1 durch die Rahmen wie beabsichtigt)
Meine Frage lautet: „ist dies eine sichere Abhilfe als der anfängliche commiter zu tun schien ein Problem zu haben, wo nur die afterPropertiesSet() mit“
Die '@ PostConstruct' keine Garantie gibt, dass Proxies sind bereits angelegt (das ist der gleiche Grund, warum' @ Transactional' funktioniert nicht für '@ PostConstruct' Methoden.Die @ PostConstruct-Methode wird direkt nach der Konstruktion und nach der Injektion der Abhängigkeiten aufgerufen, aber fast immer vor dem Punkt, an dem Proxies erzeugt wurden. Warum brauchst du es in einer @ PostConstruct-Methode? Im Allgemeinen ist ein 'ApplicationListener' besser als das Implementieren der 'SmartInitializingSingleton'-Schnittstelle anstelle von' @ PostConstruct '. –
Vielen Dank für Ihre Antwort. Wir verwenden das postconstruct, um eine Bean mit Werten zu initialisieren, die von einem anderen Service genommen wurden (der @Cacheable auf seinen Methoden hat). Wir erwarteten, dass diese Werte auch dann zwischengespeichert würden, wenn ein Postconstruct verwendet würde. Wenn dies nicht der Fall ist, würde ein Java-Dokument das Framework unterstützen, da andere Entwickler dies möglicherweise ebenfalls nicht wissen. Werde den SmartInitializingSingleton stattdessen versuchen. Vielen Dank! – user2966436
Dies wird in [dem Referenzhandbuch] erklärt (http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-factory-lifecycle-default-init-destroy-methods) lies den letzten Abschnitt dieses Abschnitts. –