Redisson 整合 Spring Cache

Redisson 官方文档写的很详细了:https://github.com/redisson/redisson/wiki/目录 参考第14.2章
这里主要描述遇到的问题:

序列化

Caused by: java.lang.RuntimeException: Class com.xx.response.MemberVO does not implement Serializable or externalizable
	at org.nustaq.serialization.FSTClazzInfo.(FSTClazzInfo.java:144)
	at org.nustaq.serialization.FSTClazzInfoRegistry.getCLInfo(FSTClazzInfoRegistry.java:129)
	at org.nustaq.serialization.FSTObjectOutput.getFstClazzInfo(FSTObjectOutput.java:534)
	at org.nustaq.serialization.FSTObjectOutput.writeObjectWithContext(FSTObjectOutput.java:416)
	at org.nustaq.serialization.FSTObjectOutput.writeObjectInternal(FSTObjectOutput.java:327)
	at org.nustaq.serialization.serializers.FSTArrayListSerializer.writeObject(FSTArrayListSerializer.java:49)
	at org.nustaq.serialization.FSTObjectOutput.writeObjectWithContext(FSTObjectOutput.java:476)
	at org.nustaq.serialization.FSTObjectOutput.writeObjectInternal(FSTObjectOutput.java:327)
	at org.nustaq.serialization.FSTObjectOutput.writeObject(FSTObjectOutput.java:294)
	at org.nustaq.serialization.FSTObjectOutput.writeObject(FSTObjectOutput.java:204)
	at org.redisson.codec.FstCodec$2.encode(FstCodec.java:261)
	... 83 common frames omitted

解决方案:实现Serializable,添加序列号即可。

public class MemberVO implements Serializable {
    private static final long serialVersionUID = -3530645211818415234L;
}

Spring Cache 是基于动态生成的 proxy 代理机制来对方法的调用进行切面,这里关键点是对象的引用问题,如果对象的方法是内部调用(即 this 引用)而不是外部引用,则会导致 proxy 失效,那么我们的注解就会失效。

@Component
public class SimpleBookRepository implements BookRepository {

    @Override
    public Book getBook() {
    	// 内部方法调用,缓存失效。
        return getDefaultBook();
    }
    
    @Cacheable("books")
    public Book getDefaultBook() {
        return new Book(isbn, "Some book");
    }

}
解决方案:
  • 修改代码逻辑,避免出现该问题。
    参考:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop-understanding-aop-proxies
  • 使用AopContent直接操作(不推荐)
    缺点:消耗性能,使业务代码强依赖Spring AOP。
@Component
public class SimpleBookRepository implements BookRepository {

    @Override
    public Book getBook() {
    	// 
        return ((BookRepository)AopContext.currentProxy()).getDefaultBook();
    }
    
    @Cacheable("books")
    public Book getDefaultBook() {
        return new Book(isbn, "Some book");
    }

}

该方法出现新的问题:

java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.
	at org.springframework.aop.framework.AopContext.currentProxy(AopContext.java:64)

解决方案:

@EnableAspectJAutoProxy(exposeProxy=true)

你可能感兴趣的:(Redis,Java)