spring boot与dubbo整合(dubbo-spring-boot-starter)

现状

团队现有框架是重度依赖dubbo,分层逻辑不清晰,导致开发模式有点重。开发一些非分布式小项目,如果使用统一的编码规范,依赖框架,就会导致被动依赖dubbo。这种开发模式,在小项目开发时,效率低下,成本过高。

解决方案

现考虑升级框架,对现有框架做拆分,以spring-boot-starter的方式,形成独立模块,单独依赖,并且可以大量简化较为繁重的xml配置。

由于框架中,最深度依赖的就是dubbo,所以首先针对rpc模块动刀,开发一个dubbo-spring-boot-starter。

实战

参照springboot的官方文档,starter项目分两个模块,starter和autoconfigure。

项目地址:https://github.com/coderzl/dubbo-spring-boot

dubbo-spring-boot

新建maven父工程,dubbo-spring-boot

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>cn.coderzl.dubbo</groupId>
	<artifactId>dubbo-spring-boot</artifactId>
	<version>1.0-SNAPSHOT</version>
	<packaging>pom</packaging>

	<name>dubbo-spring-boot</name>
	<description>dubbo for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<modules>
		<module>dubbo-spring-boot-autoconfigure</module>    
		<module>dubbo-spring-boot-starter</module>          
		<module>dubbo-api-spring-boot-test</module>         <!-- test project -->
        <module>dubbo-provider-spring-boot-test</module>    <!-- test project -->
		<module>dubbo-consumer-spring-boot-test</module>    <!-- test project -->
	</modules>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<project.model.version>1.0-SNAPSHOT</project.model.version>
		<java.version>1.8</java.version>
		<spring-boot.version>1.5.9.RELEASE</spring-boot.version>
		<zookeeper.version>3.4.6</zookeeper.version>
		<dubbo.version>2.5.7</dubbo.version>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>${spring-boot.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>


</project>

dubbo-spring-boot-autoconfigure

创建module dubbo-spring-boot-autoconfigure

pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<parent>
		<groupId>cn.coderzl.dubbo</groupId>
		<artifactId>dubbo-spring-boot</artifactId>
		<version>1.0-SNAPSHOT</version>
	</parent>

	<groupId>cn.coderzl.dubbo</groupId>
	<artifactId>dubbo-spring-boot-autoconfigure</artifactId>
	<version>${project.model.version}</version>
	<packaging>jar</packaging>

	<name>dubbo-spring-boot-autoconfigure</name>
	<description>Dubbo Configure for Spring Boot</description>


	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-autoconfigure</artifactId>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<version>${dubbo.version}</version>
			<exclusions>
				<exclusion>
					<artifactId>spring</artifactId>
					<groupId>org.springframework</groupId>
				</exclusion>
				<exclusion>
					<artifactId>zookeeper</artifactId>
					<groupId>org.apache.zookeeper</groupId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>${zookeeper.version}</version>
			<exclusions>
				<exclusion>
					<groupId>io.netty</groupId>
					<artifactId>netty</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-log4j12</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>com.101tec</groupId>
			<artifactId>zkclient</artifactId>
			<version>0.4</version>
		</dependency>
	</dependencies>

</project>

  • 属性对象

DubboProperties 装载初始自动配置的相关属性,下面的对象,只配置了我们项目中暂时用到到一些属性。。。


@ConfigurationProperties(prefix = DubboProperties.DUBBO_PREFIX)
public class DubboProperties {
    public static final String DUBBO_PREFIX = "dubbo";

    /** 消费者配置开关 默认关闭(暂未生效) */
    private boolean consumerTrigger;
    /** 生产者配置开关 默认关闭(暂未生效) */
    private boolean providerTrigger;
    /** applicationName */
    private String applicationName;
    /** 注册中心地址 */
    private String registryAddress;
    /** 启动时是否检查注册中心 */
    private boolean registryCheck =  false;
    /** 协议 默认:dubbo */
    private String protocol = "dubbo";
    /** 端口 默认 20800 */
    private int port = 20800;
    /** HOST */
    private String host;
    /** dubbo 线程数, 默认 200  */
    private int threads = 200;
    /** 重试次数 默认不重试 */
    private int retries = 0;
    /** consumerCheck 默认不检查 */
    private boolean consumerCheck = false;
    /** 消费者过滤器 多个用,隔开 */
    private String consumerFilter;
    /** 提供者者过滤器 多个用,隔开 */
    private String providerFilter;
    /** providerCheck 默认不检查 */
    private boolean providerCheck = false;
    /** group */
    private String group;
    /** 超时时间 */
    private int timeout;

    //…………省略getter/setter
}    

  • DubboAutoConfiguration

配置了一些通用的基础config。


@Configuration
@EnableConfigurationProperties(DubboProperties.class)
public class DubboAutoConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(DubboAutoConfiguration.class);

    @Autowired
    private DubboProperties dubboProperties;

    @PostConstruct
    public void checkConfigFileExists(){
        if (!StringUtils.hasText(dubboProperties.getRegistryAddress()) || !StringUtils.hasText(dubboProperties.getApplicationName())){
            throw new IllegalArgumentException("RegistryAddress or ApplicationName is null");
        }
    }

    @Bean
    @ConditionalOnMissingBean
    public ApplicationConfig getApplicationConfig(){
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName(dubboProperties.getApplicationName());
        return applicationConfig;
    }

    @Bean
    @ConditionalOnMissingBean
    public RegistryConfig getRegistryConfig(){
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress(dubboProperties.getRegistryAddress());
        registryConfig.setCheck(dubboProperties.isRegistryCheck());
        return registryConfig;
    }

    @Bean
    @ConditionalOnMissingBean
    public ProtocolConfig getProtocolConfig(){
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setName(dubboProperties.getProtocol());
        protocolConfig.setHost(dubboProperties.getHost());
        protocolConfig.setPort(dubboProperties.getPort());
        return protocolConfig;
    }

    @Bean
    @ConditionalOnMissingBean
    public MonitorConfig getMonitorConfig(){
        MonitorConfig monitorConfig = new MonitorConfig();
        monitorConfig.setProtocol("registry");
        return monitorConfig;
    }

}

  • DubboProviderAutoConfiguration
    服务提供者端初始配置

/**
 * <p> dubbo提供者自动配置 </p>
 *
 * @author coderzl
 * @Title DubboProviderAutoConfiguration
 * @date 2017/12/4 10:27
 * @package cn.coderzl.dubbo.spring.boot.autoconfigure
 */
@Configuration
@EnableConfigurationProperties(DubboProperties.class)
@AutoConfigureAfter(DubboAutoConfiguration.class)
public class DubboProviderAutoConfiguration {

    @Autowired
    private DubboProperties dubboProperties;

    @Bean
    @ConditionalOnMissingBean
    public ProviderConfig getProviderConfig(){
        ProviderConfig providerConfig = new ProviderConfig();
        providerConfig.setRetries(dubboProperties.getRetries());
        providerConfig.setFilter(dubboProperties.getConsumerFilter());
        providerConfig.setTimeout(dubboProperties.getTimeout());
        providerConfig.setGroup(dubboProperties.getGroup());
        return providerConfig;
    }
}
  • DubboConsumerAutoConfiguration
    服务消费者端自动配置

/**
 * <p> dubbo消费者自动配置 </p>
 *
 * @author coderzl
 * @Title DubboConsumerAutoConfiguration
 * @date 2017/12/4 10:26
 * @package cn.coderzl.dubbo.spring.boot.autoconfigure
 */
@Configuration
@EnableConfigurationProperties(DubboProperties.class)
@AutoConfigureAfter(DubboAutoConfiguration.class)
public class DubboConsumerAutoConfiguration {

    @Autowired
    private DubboProperties dubboProperties;

    @Bean
    @ConditionalOnMissingBean
    public ConsumerConfig getConsumerConfig(){
        ConsumerConfig consumerConfig = new ConsumerConfig();
        consumerConfig.setRetries(dubboProperties.getRetries());
        consumerConfig.setTimeout(dubboProperties.getTimeout());
        consumerConfig.setCheck(dubboProperties.isConsumerCheck());
        consumerConfig.setGroup(dubboProperties.getGroup());
        return consumerConfig;
    }
}

  • spring.factories
    在META-INF目录下配置spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
cn.coderzl.dubbo.spring.boot.autoconfigure.DubboAutoConfiguration,
cn.coderzl.dubbo.spring.boot.autoconfigure.DubboConsumerAutoConfiguration,
cn.coderzl.dubbo.spring.boot.autoconfigure.DubboProviderAutoConfiguration

dubbo-spring-boot-starter

这是一个空项目

  • pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>cn.coderzl.dubbo</groupId>
	<artifactId>dubbo-spring-boot-starter</artifactId>
	<version>${project.model.version}</version>

	<name>dubbo-spring-boot-starter</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>cn.coderzl.dubbo</groupId>
		<artifactId>dubbo-spring-boot</artifactId>
		<version>1.0-SNAPSHOT</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>cn.coderzl.dubbo</groupId>
			<artifactId>dubbo-spring-boot-autoconfigure</artifactId>
			<version>${project.model.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
	</dependencies>

</project>

  • spring.provides

在META-INF目录下创建spring.provides

provides: dubbo-spring-boot-autoconfigure

原文地址:https://www.cnblogs.com/coderzl/p/8005996.html