Dubbo(http://dubbo.io/) 是阿里的開源的一款分布式服務框架。而Spring Boot則是Spring社區這兩年致力於打造的簡化Java配置的微服務框架。
利用他們各自優勢,配置到一起,可以幫助我們構建出非常優秀的微服務。
配置Maven
使用的Dubbo的一般都是大型項目,maven項目構建也會使用parent節點,Spring Boot考慮到了這種情況,提供了dependencyManagement的方式,引入Spring Boot的包。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在具體的starter選擇上,使用spring-boot-starter,這樣spring-boot會只啟動spring的配置,而不會自動啟用什么軟件或者是網絡服務器。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
Maven的部分就配置完了
配置啟動類
Dubbo提供了一個啟動類com.alibaba.dubbo.container.Main,在Dubbo的項目中,大多數都是使用這個類啟動項目的,而這個類中會加載很多的容器,其中最重要的就是SpringContainer,這個類會讀取系統中相關的spring配置。
而在Spring Boot的體系中,則是任意寫一個啟動類,然后加注解@SpringBootApplication在這個類之上,讓spring boot能夠發現這個類,並啟動這個類的main方法。
在Spring Boot的設計中,推薦大家使用無XML配置的方式啟動項目,但大多數項目由於各種原因很難擺脫XML的束縛,這種情況下,使用@ImportResource注解引入xml配置,在@ImportResource中填寫需要引入的配置:
@ImportResource({"classpath:spring-context.xml"})
@ImportResource會自動去查找resource目錄下的文件並引入Spring Boot。
經接着,我們需要解決啟動類中main()方法的問題,一般情況下,我們寫的啟動類會使用:
SpringApplication.run(DemoApplication.class, args);
但由於Dubbo項目引用了Spring Web框架中的一些類,使得Maven也不得不導入Spring Web項目,了而Spring Boot發現跟web相關的框架就會去啟動web容器(比如Tomcat、Jetty等),並且我們的配置是沒有添加容器的,所以main()方法需要寫成:
ApplicationContext ctx = new SpringApplicationBuilder()
.sources(DemoApplication.class)
.web(false) // 沒錯,把項目設置成非web環境
.run(args);
還需要注意的是,由於使用了非常純粹的starter,而且Dubbo的網絡框架也是非阻塞的,所以我們還需使用一些方法,保持主線程的阻塞狀態。比如我使用CountDownLatch來做這件事。最終形成了以下啟動類的完整代碼:
@SpringBootApplication
@ImportResource({"classpath:spring/spring-context.xml"})
public class DemoApplication {
private static final Logger logger = LoggerFactory.getLogger(DemoApplication.class);
@Bean
public CountDownLatch closeLatch() {
return new CountDownLatch(1);
}
public static void main(String[] args) throws InterruptedException {
ApplicationContext ctx = new SpringApplicationBuilder()
.sources(DemoApplication.class)
.web(false)
.run(args);
logger.info("項目啟動!");
CountDownLatch closeLatch = ctx.getBean(CountDownLatch.class);
closeLatch.await();
}
}
好了這個類構建完成之后,我們按照Dubbo的方式配置好service,就可以打包了。
打包部署
Dubbo本身有一個比較麻煩的問題就是在打包部署,從官方的demo上來看,Dubbo打包借助了maven插件assembly,而且要寫不少的配置,而Spring Boot的工具相對來說,幾乎不需要任何的配置。在pom.xml的build節點下面,配置spring-boot-maven-plugin插件
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.5.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
命令行切換到項目的目錄之后,執行命令:
mvn package
在target目錄下面,會產生兩個文件

把demo-0.0.1-SNAPSHOT.jar拷貝到任意一個項目下啟動:

服務調用
我簡單地寫了一個consumer的測試類,從consumer項目調用項目,也是可以順利調用到這個服務的。

這個時候在provider端,也是可以consumer看到調用的情況 :

Bingo ! Dubbo running over the Spring Boot!
