SpringBoot JetCache常用问题
为什么调用同一个类的另一个方法,@Cached
注解没有生效?
JetCache的注解功能是使用Spring AOP来实现的,而Spring基于Proxy来实现AOP。 从Spring Context中获得的bean,以及通过@Autowired
注解都是代理增强过的,所以可以织入缓存相关的逻辑,同一个类中通过this调用另一个方法,不经过代理,所以JetCache的缓存逻辑以及Spring的其它AOP切面都不会生效。
JetCache暂未支持AspectJ。
一个替代方法是,在bean中通过@Autowired
注入它自己,然后在用注入的实例代替this来调用。
@Cached的key、condition等表达式中使用参数名以后缓存没有生效
javac编译器需要指定-parameters参数以后才会把参数名信息写入到字节码中,然后才能被反射机制读取,默认情况下这个参数是没有指定的。
pom中的指定方式:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
</plugins>
如果你在IDE中运行程序,光在pom中指定还不够。
在IntelliJ IDEA中设置:
在Eclipse中设置:
如何定制自己的序列化器
在Cached和CreateCache上的serialPolicy可以指向一个Spring Bean。 做一个类实现SerialPolicy接口,在Spring Context中创建该类的实例(假设名字为myBean),在Cached和CreateCache注解上设置serialPolicy="bean:myBean"即可。
更进一步,如果想把自定义的序列化器设置为默认的,可以声明一个SpringConfigProvider,然后覆盖其parseValueEncoder和parseValueDecoder方法:
@Bean
public SpringConfigProvider springConfigProvider() {
return new SpringConfigProvider() {
@Override
public Function<Object, byte[]> parseValueEncoder(String valueEncoder) {
if(valueEncoder.equals("xxx")){
return MyEncoder();
}else{
return super.parseValueEncoder(valueEncoder);
}
};
@Override
public Function<byte[], Object> parseValueDecoder(String valueDecoder) {
.........
}
}
我想要JSON序列化器
jetcache老版本中是有三个序列化器的:java、kryo、fastjson。 但是fastjson做序列化兼容性不是特别好,并且某次升级以后单元测试就无法通过了,怕大家用了以后觉得有坑,就把它废弃了。 现在默认的序列化器是性能最差,但是兼容性最好,大家也最熟悉的java序列化器。
需要JSON序列化器的,自己动手吧,可以参考这里,还是挺简单的:
useIdentityNumber属性用于修改serialPolicy以后的值兼容(比如serialPolicy改成新的了,redis里面还是旧的)。
idea的编译参数:”-parameters“
在使用Idea进行本地调试时,需进行如下配置:
Preferences -> "Build, Execution, Deployment" -> Compiler -> "Java Compiler"
- "Project bytecode version"设置为1.8
- "Additional command line parameters"添加"-parameters"
这样,Idea在编译时,就会编译出带参数名称的(id, name, age)的文件,当不添加"-parameters",通过(arg0, arg1, arg2)这种方式也可以进行测试。
EnableMethodCache配置
注意包名后面不能有 .*。如: "com.topcheer.task.*"
只能写成"com.topcheer.task"
。
@SpringBootApplication(scanBasePackages = {"com.alicp.jetcache.autoconfigure","com.topcheer.task"})
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableMethodCache(basePackages = "com.topcheer.task")
@EnableCreateCacheAnnotation
public class TaskServiceApplication {
public static void main(String[] args) {
SpringApplication.run(TaskServiceApplication.class, args);
}
}
本文由 创作,采用 知识共享署名4.0 国际许可协议进行许可。本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为: 2021/03/25 01:46