Repository navigation
希望支持 Jedis 3.x #1647
Copy link
Copy link
Closed
Labels
Description
希望能够支持Jedis 3.x。
个人建议
ConfigStorage Jedis的实现构造应该统一使用WxRedisOps来构造,因为不使用统一会出现以下问题。
版本编号
- WxJava 3.8.0
- Jedis 3.2.0
- spring-boot-starter-data-redis 2.3
问题体现
异常环境
- Java JDK 1.8.0_201
- centos-release-7-6.1810.2.el7.centos.x86_64
环境差异
windows 10,jdk 1.8.0_171 下能正常运行。
代码实现
@Bean
public WxMpService wxMpService(StringRedisTemplate redis, WeChatConfig cfg) {
RedisTemplateWxRedisOps ops = new RedisTemplateWxRedisOps(redis);
WxMpRedisConfigImpl config = new WxMpRedisConfigImpl(ops, "wx");
config.setAppId(cfg.getAppId());
config.setSecret(cfg.getSecret());
config.setToken(cfg.getToken());
config.setAesKey(cfg.getEncodingAesKey());
WxMpService wxService = new WxMpServiceImpl();
wxService.setWxMpConfigStorage(config);
return wxService;
}异常日志
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'wechatController': Unsatisfied dependency expressed through field 'wxMpServiceMap'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'wxMpService' defined in class path resource [com/egu365/api/config/WebConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [me.chanjar.weixin.mp.api.WxMpService]: Factory method 'wxMpService' threw exception; nested exception is java.lang.NoClassDefFoundError: redis/clients/util/Pool
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:895)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at com.egu365.api.Egu365RestApiApplication.main(Egu365RestApiApplication.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:109)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'wxMpService' defined in class path resource [com/egu365/api/config/WebConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [me.chanjar.weixin.mp.api.WxMpService]: Factory method 'wxMpService' threw exception; nested exception is java.lang.NoClassDefFoundError: redis/clients/util/Pool
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1524)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1488)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1407)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1264)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1226)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
... 28 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [me.chanjar.weixin.mp.api.WxMpService]: Factory method 'wxMpService' threw exception; nested exception is java.lang.NoClassDefFoundError: redis/clients/util/Pool
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651)
... 44 common frames omitted
Caused by: java.lang.NoClassDefFoundError: redis/clients/util/Pool
at com.egu365.api.config.WebConfig.wxMpService(WebConfig.java:212)
at com.egu365.api.config.WebConfig$$EnhancerBySpringCGLIB$$14eddc6.CGLIB$wxMpService$22(<generated>)
at com.egu365.api.config.WebConfig$$EnhancerBySpringCGLIB$$14eddc6$$FastClassBySpringCGLIB$$3f0fb69c.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
at com.egu365.api.config.WebConfig$$EnhancerBySpringCGLIB$$14eddc6.wxMpService(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 45 common frames omitted
Caused by: java.lang.ClassNotFoundException: redis.clients.util.Pool
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:129)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 56 common frames omitted
原因分析
使用Spring Data Redis,本生的目的是屏蔽Jedis客户端复杂和版本差异。
RedisTemplateWxRedisOps ops = new RedisTemplateWxRedisOps(template);
使用RedisTemplateWxRedisOps时,只要SpringDataRedis能正常运行,WxMpRedisConfigImpl也应该能正常运行。
- 但由于windows 和linux下的jdk对class加载方式有差异。
// 编号1
// 未使用的构造
public WxMpRedisConfigImpl(JedisPool jedisPool) {
this(new JedisWxRedisOps(jedisPool), "wx");
}
// 编号2
// 使用的构造器
public WxMpRedisConfigImpl(WxRedisOps redisOps, String keyPrefix) {
this.redisOps = redisOps;
this.keyPrefix = keyPrefix;
}理论上来说,使用2号构造器,应该能正常使用,但是在Linux环境,Jdk确会加载1号构造器的依赖关系。
如果移除1号构造号,统一WxRedisOps来构造,就可以避免这样的问题。
WxMpRedisConfigImpl和JedisWxRedisOps(JedisPool jedisPool)没有直接依赖关系。也就不会去加载redis.clients.util.Pool。
- 这样能够统一依赖,降压依赖的复杂程度。
- 能够更加灵活,如果有特殊实现,也只需关注WxRedisOps接口。
_ 以上仅个人建议,希望项目越来越完善,成代码中最靓的仔 _
Reactions are currently unavailable
Activity
xuxinlong001 commentedon Jul 2, 2020
spring-boot-starter-data-redis 已经默认支持lettuce,不支持jedis,所以一直报错,建议3.8版本去除对jedis的依赖
binarywang commentedon Jul 2, 2020
感谢楼主建议,本来SDK只关注微信相关接口实现,最初是没有引入redis相关依赖的,但后期为了满足大家需求,引入了相关实现,也仅是作为参考。
如果大家有更好的实现,欢迎随时提供PR。
gyjx commentedon Jul 2, 2020
嗯 这就解决了我,为什么windows下启动没错,linux启动报错的问题!谢谢
binarywang commentedon Jul 2, 2020
#1605 跟此问题中提到的方法类似,准备去掉第一个构造方法
🎨 #1647 优化公众号redis配置支持,去掉容易导致问题的构造方法
binarywang commentedon Jul 6, 2020
请使用最新测试版本看是否还有问题
prosaically commentedon Jul 6, 2020
weixin-java-miniapp 的 config
WxMaRedisBetterConfigImpl也需要调整binarywang commentedon Jul 6, 2020
建议可以自己先在本地测试,没问题后直接提交PR,这样会比较高效些
🎨 #1647 优化小程序redis配置支持,去掉容易导致问题的构造方法