Spring AOP не работает с самовывозом, таким как @CachePut - PullRequest
0 голосов
/ 19 января 2019

Я работаю над аннотацией кеширования Spring, но обнаружил, что в ней происходят странные вещи.

Скажем, я вызываю метод в том же классе обслуживания, в котором есть аннотация @CachePut. Это не кэшируется.

Если я перенесу этот метод в какой-нибудь другой файл реализации службы и вызову этого метода будет работать кэширование.

Мне нужно знать, что я делаю неправильно.

1 Ответ

0 голосов
/ 19 января 2019

Предположим, вы пишете следующий класс с @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.

...