rocketmq-spring-boot-starter支持SpringBoot 1.x(spring-context 4.x)版本

5 篇文章 0 订阅
2 篇文章 0 订阅

1 问题说明

由于历史原因,项目使用的是SpringBoot1.x版本,而且由于种种原因,不能升级。在项目开发迭代过程中,决定使用RocketMQ作为消息中间件,因为是SpringBoot项目,理所应当的引入了rocketmq-spring-boot-starter依赖。但在使用@RocketMQMessageListener注解时,项目就启动不起来了,错误信息如下:

image-20230627231023032

2023-06-27 22:39:35.675ERROR [service,[TID: N/A],,,] 52424 --- [           main] o.s.b.SpringApplication                  : Application startup failed
java.lang.NoClassDefFoundError: org/springframework/beans/factory/config/BeanDefinitionCustomizer
	at org.apache.rocketmq.spring.autoconfigure.ListenerContainerConfiguration.registerContainer(ListenerContainerConfiguration.java:114)
	at java.util.HashMap.forEach(HashMap.java:1288)
	at org.apache.rocketmq.spring.autoconfigure.ListenerContainerConfiguration.afterSingletonsInstantiated(ListenerContainerConfiguration.java:79)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:781)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
	at xxx.Application.main(ServiceApplication.java:25)
Caused by: java.lang.ClassNotFoundException: org.springframework.beans.factory.config.BeanDefinitionCustomizer
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 13 more

对应报错位置:

image-20230627224446364

对应代码为:

image-20230627224617301

2 问题分析

分析:SpringBoot1.x使用的spring-context4.x版本,GenericApplicationContext.registerBean方法是5.0版本才出现,那该如何解决以下问题?

第一个想法,当然是升级SpringBoot版本到2.x,但是,由于种种限制,SpringBoot版本并没有那么好升级。

于是就产生了第二个想法,单独升级spring-context版本,经过测试后,发现也不行。

于是翻阅github的issue发现,有人提交过补丁代码,但是被拒绝了,issue链接 对应的修改代码链接

研究了一下他的思路,主要是通过使用GenericApplicationContext.registerBeanDefinition来支持SpringBoot 1.x版本,因为该方法在spring-context 4.x版本中已经拥有,所以就可以兼容SpringBoot 1.x版本。

3 具体修复方式

3.1 下载spring-boot-starter源码

地址:https://github.com/apache/rocketmq-spring/tags

image-20230627225930661

3.2 解压后,用编辑器打开

3.3 修改代码

3.3.1 在ListenerContainerConfiguration类中增加方法:

private BeanDefinition buildBeanDefinition(String name, Object bean,
                                           RocketMQMessageListener annotation) {
    String nameServer = environment.resolvePlaceholders(annotation.nameServer());
    nameServer = StringUtils.isEmpty(nameServer) ? rocketMQProperties.getNameServer() : nameServer;
    String accessChannel = environment.resolvePlaceholders(annotation.accessChannel());
    String tags = environment.resolvePlaceholders(annotation.selectorExpression());
    BeanDefinitionBuilder builder = BeanDefinitionBuilder
        .genericBeanDefinition(DefaultRocketMQListenerContainer.class)
        .addPropertyValue("rocketMQMessageListener", annotation)
        .addPropertyValue("nameServer", nameServer)
        .addPropertyValue("topic", environment.resolvePlaceholders(annotation.topic()))
        .addPropertyValue("consumerGroup", environment.resolvePlaceholders(annotation.consumerGroup()))
        .addPropertyValue("tlsEnable", environment.resolvePlaceholders(annotation.tlsEnable()))
        .addPropertyValue("messageConverter", rocketMQMessageConverter.getMessageConverter())
        .addPropertyValue("name", name);

    if (!StringUtils.isEmpty(accessChannel)) {
        builder.addPropertyValue("accessChannel", AccessChannel.valueOf(accessChannel));
    }

    if (!StringUtils.isEmpty(tags)) {
        builder.addPropertyValue("selectorExpression", tags);
    }
    if (RocketMQListener.class.isAssignableFrom(bean.getClass())) {
        builder.addPropertyValue("rocketMQListener", bean);
    } else if (RocketMQReplyListener.class.isAssignableFrom(bean.getClass())) {
        builder.addPropertyValue("rocketMQReplyListener", bean);
    }
    return builder.getBeanDefinition();
}

3.3.2 修改对应报错调用代码

image-20230627230115115

BeanDefinition beanDefinition = buildBeanDefinition(containerBeanName, bean, annotation);
genericApplicationContext.registerBeanDefinition(containerBeanName, beanDefinition);

修改源码后,重新打包,项目使用修改后的依赖发现可以正常使用,问题解决。

说明:以上方式虽然能解决问题,但是,个人推荐还是升级SpringBoot版本,毕竟1.x版本确实有点老了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
根据您提供的引用内容,您遇到的问题是在配置pom.xml文件时出现了依赖问题,具体是"Dependency 'org.springframework.boot:spring-boot-starter-test' not found"。您在各类网站上查找解决方法都没有找到有效的解决方案,直到在CSDN上找到了一篇文章,通过在Maven中导入相关包解决了问题。同时,您还提到了另外一个引用内容,其中包含了关于Maven安装的信息。 对于您的问题,您可以尝试在Maven中导入"spring-boot-starter-test"包来解决依赖问题。另外,您还提到了关于Thymeleaf的引用内容,但是您并没有提出具体的问题。如果您有关于"spring-boot-starter-thymeleaf"和"org.thymeleaf.context.Context"的问题,请提供更多细节,我将尽力为您解答。 #### 引用[.reference_title] - *1* [Dependency ‘org.springframework.bootspring-boot-starter-testnot found 的解决方法](https://blog.csdn.net/m0_67391270/article/details/126327077)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [MyBatis-Spring-Boot-Starter学习](https://blog.csdn.net/m0_67391907/article/details/126463485)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丶只有影子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值