Предположим, вы пишете следующий класс с @CachePut
,
public class FooBean implements Foo{
@CachePut
public String doSomething(){
}
}
. Spring позади сцены создаст прокси-сервер AOP, который обернет ваш класс так, что он сможет применять некоторые кеширующие магические коды до или после вызова фактического@CachePut
метод.Вы можете думать, что прокси-сервер AOP выглядит следующим образом:
public class FooBeanProxy implements Foo{
private FooBean fooBean;
public String doSomething(){
//Maybe there are some caching magic codes here....
fooBean.doSomething()
//Maybe there are other caching magic codes here........
}
}
Если я перенесу этот метод в какой-нибудь другой файл реализации службы и вызову этого метода будет работать кэширование.
Предположим,Чтобы вызвать метод @CachePut
, выполните следующие действия:
@Component
public class App {
//FooBeanProxy actually injected HERE
@Autowired
private Foo foo;
public void startDoing(){
foo.doSomething();
}
}
То, что Spring вводит для вас, - FooBeanProxy
, но не ваш FooBean.Итак, когда вы вызываете этот метод @CachePut
, магические коды кэширования будут работать так, как вы вызываете FooBeanProxy
Скажем, я вызываю метод в том же классе обслуживания, который имеет аннотацию @CachePut вЭто.Это не кэшируется.
Это означает, что это само-вызов.Вы вызываете эту ссылку, которая является вашим FooBean
экземпляром, но уже не FooBeanProxy
.Таким образом, эта магия кеширования никогда не будет выполнена, и, следовательно, результат не будет кеширован.
На самом деле то, что я говорю выше, уже упоминалось в документах .Если вы все еще хотите, чтобы @CachePut
вступил в силу в случае самостоятельного вызова, вы можете использовать ужасное и уродливое решение AopContext.currentProxy()
, упомянутое в документах , или использовать AspectJ
.