Presta atención porque en este post vas a encontrar la solución que buscas.Esta noticia fue aprobado por nuestros expertos para asegurar la calidad y exactitud de nuestro contenido.
Solución:
Creo que así es como funciona. Por lo que recuerdo haber leído, se genera una clase de proxy que intercepta todas las solicitudes y responde con el valor almacenado en caché, pero las llamadas ‘internas’ dentro de la misma clase no obtendrán el valor almacenado en caché.
De https://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable
Solo se interceptan las llamadas a métodos externos que llegan a través del proxy. Esto significa que la autoinvocación, en efecto, un método dentro del objeto de destino que llama a otro método del objeto de destino, no conducirá a una intercepción de caché real en tiempo de ejecución incluso si el método invocado está marcado con @Cacheable.
Desde Spring 4.3, el problema podría resolverse utilizando el autocableado sobre @Resource
anotación:
@Component
@CacheConfig(cacheNames = "SphereClientFactoryCache")
public class CacheableSphereClientFactoryImpl implements SphereClientFactory
/**
* 1. Self-autowired reference to proxified bean of this class.
*/
@Resource
private SphereClientFactory self;
@Override
@Cacheable(sync = true)
public SphereClient createSphereClient(@Nonnull TenantConfig tenantConfig)
// 2. call cached method using self-bean
return self.createSphereClient(tenantConfig.getSphereClientConfig());
@Override
@Cacheable(sync = true)
public SphereClient createSphereClient(@Nonnull SphereClientConfig clientConfig)
return CtpClientConfigurationUtils.createSphereClient(clientConfig);
El siguiente ejemplo es lo que uso para acceder al proxy desde el mismo bean, es similar a la solución de @mario-eis, pero lo encuentro un poco más legible (tal vez no lo sea:-). De todos modos, me gusta mantener las anotaciones @Cacheable en el nivel de servicio:
@Service
@Transactional(readOnly=true)
public class SettingServiceImpl implements SettingService {
@Inject
private SettingRepository settingRepository;
@Inject
private ApplicationContext applicationContext;
@Override
@Cacheable("settingsCache")
public String findValue(String name)
Setting setting = settingRepository.findOne(name);
if(setting == null)
return null;
return setting.getValue();
@Override
public Boolean findBoolean(String name)
String value = getSpringProxy().findValue(name);
if (value == null)
return null;
return Boolean.valueOf(value);
/**
* Use proxy to hit cache
*/
private SettingService getSpringProxy()
return applicationContext.getBean(SettingService.class);
...
Véase también Comenzar una nueva transacción en Spring bean