dubbo和springcloud问题解决——interface not allow null

环境

dubbo版本: 2.7.3

springCloud版本: 2.2.0

复现步骤

当使用@Service注解注入dubbo provider到Spring容器中时,在dubbo provider的bean对象里依赖SpringCloud的bean时,触发报错,应用报错无法启动!

dubbo provider bean

@Service(registry = "dubbo-registry", interfaceClass = DubboProvideFacade.class)
public class DubboProviderServiceImpl implements DubboProvideFacade {
  @Resource
	private FeignClient feignClient;
  ······
}

SpringCloud Client

@FeignClient(name = "feignClient", url = "${feign.client.config.url}", configuration = FeignClientInterceptor.class)
public interface FeignClient {
  	······
}

报错

报错图片

Caused by: java.lang.IllegalStateException: <dubbo:service interface="" /> interface not allow null!
	at org.apache.dubbo.config.ServiceConfig.checkAndUpdateSubConfigs(ServiceConfig.java:297)
	at org.apache.dubbo.config.ServiceConfig.export(ServiceConfig.java:358)
	at org.apache.dubbo.config.spring.ServiceBean.export(ServiceBean.java:327)
	at org.apache.dubbo.config.spring.ServiceBean.onApplicationEvent(ServiceBean.java:105)
	at org.apache.dubbo.config.spring.ServiceBean.onApplicationEvent(ServiceBean.java:51)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402)
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:408)
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359)
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:896)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:552)
	at org.springframework.cloud.context.named.NamedContextFactory.createContext(NamedContextFactory.java:136)
	at org.springframework.cloud.context.named.NamedContextFactory.getContext(NamedContextFactory.java:101)
	at org.springframework.cloud.context.named.NamedContextFactory.getInstance(NamedContextFactory.java:145)
	at org.springframework.cloud.openfeign.FeignClientFactoryBean.get(FeignClientFactoryBean.java:224)
	at org.springframework.cloud.openfeign.FeignClientFactoryBean.feign(FeignClientFactoryBean.java:85)
	at org.springframework.cloud.openfeign.FeignClientFactoryBean.getTarget(FeignClientFactoryBean.java:261)
	at org.springframework.cloud.openfeign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:251)
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:171)
	... 142 common frames omitted

原因

这个错误是由 Spring Cloud Feign 设计引起的,每个@FeignClient都会生成一个带有新子 Spring 的 Feign 代理,该子 SpringApplicationContext可能会在其 parent 之前刷新ApplicationContext。如果有注解@Service的 Dubbo 服务 bean 被子上下文扫描到,这个 DubboServiceBean也会被初始化,并且不能保证其依赖的 Spring bean 在那个时候已经准备好

解决方式

方式一(已验证)

FeignClient使用ApplicationContextAware进行获取

首先写一个SpringBean获取工具类
@Component
public class SpringBeanUtil implements ApplicationContextAware {
    private static ApplicationContext appContext;

    private static boolean hasBean(String name){
        return appContext.containsBean(name);
    }

    public static Object getBeanByName(String name) throws BeansException {
        return appContext.getBean(name);
    }

    public static Object getBeanByType(Class requiredType) throws BeansException {
        return appContext.getBean(requiredType);
    }

    public static Object getBeanIfPresent(String name){
        if(hasBean(name)){
            return getBeanByName(name);
        }
        return null;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        setAppContext(applicationContext);
    }

    private static synchronized void setAppContext(ApplicationContext appContext) {
        SpringBeanUtil.appContext = appContext;
    }
}
通过Util获取FeignClient而不是Spring注入的方式
FeignClient client = SpringContextUtils.getBean(FeignClient.class)

方式二

升级dubbo版本至2.7.9

据说在2.7.9解决了改问题

方式三

一个不完美的解决方法是,让FeignClient以懒注入的方式进行注入

@Service(registry = "dubbo-registry", interfaceClass = DubboProvideFacade.class)
public class DubboProviderServiceImpl implements DubboProvideFacade {
  @Resource
  @Lazy
	private FeignClient feignClient;
  ······
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dubbo和Spring Cloud都是微服务架构中常用的框架。Dubbo相对于Spring Cloud来说,在一些模块功能方面的实现可能没有Spring Cloud齐全,但它也有自己的一些优势。Dubbo是一个高性能的RPC框架,它提供了服务发现、服务流量管理、配置和扩展等功能。而Spring Cloud是一个更全面的微服务框架,它提供了更多的组件和功能,包括服务注册与发现、负载均衡、熔断器、配置管理等。你可以在Spring Cloud的官网上了解更多关于Spring Cloud的信息\[2\]。如果要比较Dubbo和Spring Cloud的优缺点,可以参考一些文章或文档,其中会详细介绍它们的各个组件的对比\[3\]。 #### 引用[.reference_title] - *1* *3* [Dubbo 简介以及和 Spring Cloud的对比](https://blog.csdn.net/CXgeng/article/details/123171102)[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^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [SpringCloudDubbo的比较](https://blog.csdn.net/Follow_24/article/details/89283802)[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^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值