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

司寇光华
2023-12-01

现状

团队现有框架是重度依赖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

 类似资料: