2

私は、キャッシュ実装として ehcache を使用して、Spring 3.1 アノテーション キャッシュに取り組んでいます。

このような戻り値を持つメソッド

@Cacheable("cache")
public MyObject getObj(Object param);

初めて myobject の戻り値を取得しましたが、これは編集可能です。ehcache は、「copyOnRead」または「copyOnWrite」を設定することで、そのために何かを行うことができます。読み取り/書き込み時にオブジェクトを強制的にシリアル化します。しかし、最初はスプリングはキャッシュから値を取得せず、常にメソッド自体によって返されます。

読み取り専用の戻り値を取得する方法はありますか?

4

3 に答える 3

3

戻り値のコピーを常に作成する独自のアスペクトを作成できます。これにより、一部の Ehcache 設定から独立できます。

最初は、次のようなマーカー アノテーション@CopyReturnValueがポイントカットを表現するのに適しています。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CopyReturnValue {
}

これで、アスペクトはポイントカット式にこの注釈を使用できます。

@Aspect
@Component
public class CopyReturnValueAspect {
    @Around("@annotation(CopyReturnValue)")
    public Object doCopyReturnValue(ProceedingJoinPoint pjp) throws Throwable {
        Object retVal = pjp.proceed();
        Object copy = BeanUtils.cloneBean(retVal); // create a copy in some way
        return copy;
    }
}

最後に、アノテーションをメソッドに追加します。

@CopyReturnValue
@Cacheable("cache")
public MyObject getObj(Object param);

例として、返された値のコピーを作成するために使用しますCopyReturnValueAspectBeanUtilsこのトピックの詳細については、ある Java Bean から別の Java Bean にプロパティをコピーする方法を参照してください。

ああ、Spring 構成で @AspectJ サポートを有効にしていない場合は、有効にすることを忘れないでください。

<aop:aspectj-autoproxy />
于 2012-06-12T22:15:53.970 に答える
0

私のために働いた少し汚い解決策を見つけました。返されたオブジェクトと同じプロパティを含む別のクラスを作成し、返されたオブジェクトを ModelMapper を使用して新しいオブジェクトにマップしました。たとえば、クラス MyObject があります。

    public class MyObject {
     private Long id;
     private Long label;

    //getters and setters
    }

新しい Created クラス:

public class MyObjectCopy {
    private Long id;
    private Long label;

    //getters and setters
}

MyObject を返すキャッシュ可能なメソッド:

 @Cacheable("cache")
public MyObject getMyObject();

そして、キャッシュが変更されるのを防ぐために: 私はそのオブジェクトを自分の classCopy にマップしなければなりません。

MyObjectCopy myObjectCopy = modelMapper.map(myobject, MyObjectCopy.class);

ネストされたオブジェクトのコピー クラスを作成することを忘れないでください。

于 2020-07-02T15:59:03.707 に答える