SpringBoot 整合使用dubbo

这里主要是按照teaey作者的spring-boot-starter-dubbo框架进行一些变化的使用

依赖包:

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.8.4</version>
  <exclusions>
    <exclusion>
      <groupId>org.springframework</groupId>
      <artifactId>spring</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </exclusion>
    <exclusion>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
    </exclusion>
    <exclusion>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<dependency>
  <groupId>com.101tec</groupId>
  <artifactId>zkclient</artifactId>
  <version>0.10</version>
  <exclusions>
    <exclusion>
      <artifactId>slf4j-api</artifactId>
      <groupId>org.slf4j</groupId>
    </exclusion>
    <exclusion>
      <artifactId>log4j</artifactId>
      <groupId>log4j</groupId>
    </exclusion>
    <exclusion>
      <artifactId>slf4j-log4j12</artifactId>
      <groupId>org.slf4j</groupId>
    </exclusion>
  </exclusions>
</dependency>

注意dubbo里面要去除mybatis依赖,不然会跟现有的冲突

工具类库:

DubboProperties:

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.MethodConfig;
import com.alibaba.dubbo.config.ModuleConfig;
import com.alibaba.dubbo.config.MonitorConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.ProviderConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * Created by qhong on 2018/12/29 11:18
 **/
@ConfigurationProperties(prefix = "spring.dubbo")
@Data
public class DubboProperties {

	private ApplicationConfig application;

	private RegistryConfig registry;

	private ProtocolConfig protocol;

	private MonitorConfig monitor;

	private ProviderConfig provider;

	private ModuleConfig module;

	private MethodConfig method;

	private ConsumerConfig consumer;

}

DubboAutoConfiguration

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.MethodConfig;
import com.alibaba.dubbo.config.ModuleConfig;
import com.alibaba.dubbo.config.MonitorConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.ProviderConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by qhong on 2018/12/29 11:19
 **/
@Configuration
@EnableConfigurationProperties(DubboProperties.class)
public class DubboAutoConfiguration {
	@Autowired
	private DubboProperties dubboProperties;

	@Bean
	public ApplicationConfig requestApplicationConfig() {
		ApplicationConfig applicationConfig = dubboProperties.getApplication();
		if (applicationConfig == null) {
			applicationConfig = new ApplicationConfig();
		}
		return applicationConfig;
	}

	@Bean
	public RegistryConfig requestRegistryConfig() {
		RegistryConfig registryConfig = dubboProperties.getRegistry();
		if (registryConfig == null) {
			registryConfig = new RegistryConfig();
		}
		return registryConfig;
	}

	@Bean
	public ProtocolConfig requestProtocolConfig() {
		ProtocolConfig protocolConfig = dubboProperties.getProtocol();
		if (protocolConfig == null) {
			protocolConfig = new ProtocolConfig();
		}
		return protocolConfig;
	}

	@Bean
	public MonitorConfig requestMonitorConfig() {
		MonitorConfig monitorConfig = dubboProperties.getMonitor();
		if (monitorConfig == null) {
			monitorConfig = new MonitorConfig();
		}
		return monitorConfig;
	}

	@Bean
	public ProviderConfig requestProviderConfig() {
		ProviderConfig providerConfig = dubboProperties.getProvider();
		if (providerConfig == null) {
			providerConfig = new ProviderConfig();
		}
		return providerConfig;
	}

	@Bean
	public ModuleConfig requestModuleConfig() {
		ModuleConfig moduleConfig = dubboProperties.getModule();
		if (moduleConfig == null) {
			moduleConfig = new ModuleConfig();
		}
		return moduleConfig;
	}

	@Bean
	public MethodConfig requestMethodConfig() {
		MethodConfig methodConfig = dubboProperties.getMethod();
		if (methodConfig == null) {
			methodConfig = new MethodConfig();
		}
		return methodConfig;
	}

	@Bean
	public ConsumerConfig requestConsumerConfig() {
		ConsumerConfig consumerConfig = dubboProperties.getConsumer();
		if (consumerConfig == null) {
			consumerConfig = new ConsumerConfig();
		}
		return consumerConfig;
	}

}

服务提供者:

import com.alibaba.dubbo.config.ServiceConfig;
import com.alibaba.dubbo.config.annotation.Service;
import com.jsy.payment.api.CustomerOpenAccountFacade;
import com.jsy.payment.api.PaymentFacade;
import com.jsy.payment.api.PaymentQueryFacade;
import io.dubbo.springboot.DubboProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * Dubbo服务配置BEAN风格暴露
 *
 */
@Configuration
public class DubboProviderConfig implements ApplicationContextAware {

    private DubboProperties dubboProperties;

    private ApplicationContext applicationContext;

    private final static Logger LOGGER = LoggerFactory.getLogger(ExportConfig.class);

    @Value("${spring.dubbo.export.group}")
    private String exportGroup;

    /**
     * 暴露接口
     */
    public static Class<?>[] EXPORT_SERVICE_CLASSES = null;

    static {
        EXPORT_SERVICE_CLASSES = new Class<?>[] {
                PaymentFacade.class,
                PaymentQueryFacade.class,
                CustomerOpenAccountFacade.class
        };
    }

    @PostConstruct
    public void init() {
        exportServices(EXPORT_SERVICE_CLASSES);
    }

    private void exportServices(Class<?>[] exportServiceClasses) {
        if (exportServiceClasses != null) {
            for (Class<?> serviceInterfaceClaz : exportServiceClasses) {
                try {
                    Service serviceAnnotation = serviceInterfaceClaz.getAnnotation(Service.class);
                    ServiceConfig serviceConfig = serviceAnnotation == null? new ServiceConfig<>() : new ServiceConfig<>(serviceAnnotation);
                    serviceConfig.setApplication(dubboProperties.getApplication());
                    serviceConfig.setRegistry(dubboProperties.getRegistry()); // 多个注册中心可以用setRegistries()
                    serviceConfig.setProtocol(dubboProperties.getProtocol()); // 多个协议可以用setProtocols()
                    serviceConfig.setInterface(serviceInterfaceClaz);
                    serviceConfig.setRef(this.applicationContext.getBean(serviceInterfaceClaz));
                    serviceConfig.setVersion(dubboProperties.getRegistry().getVersion()); // 接口暴露版本号
                    serviceConfig.setGroup(exportGroup);
                    serviceConfig.export();
                    LOGGER.info("Service:{} exported successfully.", serviceInterfaceClaz.getName());
                } catch (Exception e) {
                    LOGGER.error("Service interface export error happened, interface className:{}, err:{}", serviceInterfaceClaz.getName(), e);
                }
            }
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        this.dubboProperties = this.applicationContext.getBean(DubboProperties.class);
    }
}

application.properties:

# dubbo配置
spring.dubbo.application.name=assets-payment-server
spring.dubbo.registry.address=zookeeper://18.16.200.41:2181?backup=18.16.200.43:2181,18.16.200.44:2181
spring.dubbo.registry.timeout=300000
spring.dubbo.registry.version=1.0.0
spring.dubbo.registry.group=
spring.dubbo.protocol.port=20882
## 本机的IP地址
spring.dubbo.protocol.host=
spring.dubbo.protocol.name=dubbo
spring.dubbo.scan=
## 设置Module
spring.dubbo.module.default=false

spring.dubbo.export.group=ddv

这个方法不需要使用dubbo原生的@Service,这样就可以随时切换esb等其他rpc框架,低耦合

服务消费者:

DubboConsumerConfig:

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.jsy.payment.api.CustomerOpenAccountFacade;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DubboConsumeConfig {

	@Value("${spring.dubbo.reference.group}")
	private String group;
	@Value("${spring.dubbo.reference.version}")
	private String version;
	@Value("${spring.dubbo.reference.protocol}")
	private String protocol;

	@Autowired
	private RegistryConfig registryConfig;
	@Autowired
	private ConsumerConfig consumerConfig;
	@Autowired
	private ApplicationConfig applicationConfig;

	private void setCommon(ReferenceConfig reference) {
		reference.setRegistry(registryConfig);
		reference.setConsumer(consumerConfig);
		reference.setApplication(applicationConfig);
		reference.setProtocol(protocol);
		reference.setVersion(version);
		if(StringUtils.isNotBlank(group)){
			reference.setGroup(group); //解决生产double引用product1.2的注册服务问题
		}
	}

	@Bean
	public CustomerOpenAccountFacade getCustomerOpenAccountFacade() {
		ReferenceConfig<CustomerOpenAccountFacade> reference = new ReferenceConfig<>();
		reference.setInterface(CustomerOpenAccountFacade.class);
		setCommon(reference);
		CustomerOpenAccountFacade customerOpenAccountFacade = reference.get();
		return customerOpenAccountFacade;
	}
}

application.properties:

# dubbo配置
spring.dubbo.application.name=huishi-server
spring.dubbo.registry.address=zookeeper://18.16.200.41:2181?backup=18.16.200.43:2181,18.16.200.44:2181
spring.dubbo.registry.check=true
spring.dubbo.registry.register=true
spring.dubbo.registry.timeout=10000
spring.dubbo.registry.group=

spring.dubbo.consumer.timeout=30000
spring.dubbo.consumer.retries=0
#spring.dubbo.consumer.check=true

spring.dubbo.reference.group=DEV
spring.dubbo.reference.version=1.0.0
spring.dubbo.reference.protocol=dubbo

然后直接调用CustomerOpenAccountFacade实例即可。

参考:

官方文档

incubator-dubbo 源码

SpringBoot整合dubbo

Spring boot 整合Dubbo

Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例

apache/incubator-dubbo-spring-boot-project

Springboot+dubbo 解决@Reference 注解为null情况

Dubbo+SpringBoot整合: 依赖注入Null Pointer Exception的问题

使用spring-boot-starter-dubbo

teaey/spring-boot-starter-dubbo

posted @ 2018-12-29 15:08  hongdada  阅读(1558)  评论(0编辑  收藏  举报