团队现有框架是重度依赖dubbo,分层逻辑不清晰,致使开发模式有点重。开发一些非分布式小项目,若是使用统一的编码规范,依赖框架,就会致使被动依赖dubbo。这种开发模式,在小项目开发时,效率低下,成本太高。java
现考虑升级框架,对现有框架作拆分,以spring-boot-starter的方式,造成独立模块,单独依赖,而且能够大量简化较为繁重的xml配置。git
因为框架中,最深度依赖的就是dubbo,因此首先针对rpc模块动刀,开发一个dubbo-spring-boot-starter。github
参照springboot的官方文档,starter项目分两个模块,starter和autoconfigure。spring
新建maven父工程,dubbo-spring-bootapache
pom文件api
<?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>
建立module dubbo-spring-boot-autoconfigurespringboot
pom.xml文件app
<?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 }
配置了一些通用的基础config。maven
@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; } }
/** * <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; } }
/** * <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; } }
# 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
这是一个空项目
<?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>
在META-INF目录下建立spring.provides
provides: dubbo-spring-boot-autoconfigure