Dubbo-BaseBuild
环境准备新建一个空的project,分别三个model
model名称 model类型 说明 common_interface java类型空项目 用于存放服务提供者和服务消费者的公共接口,避免写两次而已 consumer springboot空项目 消费者服务依赖 common_interface
modelprovider springboot空项目 提供者服务依赖 common_interface
model上面项目建立好,model依赖关系加好之后,下面开始引入dubbo框架
两个springboot项目都引入dubbo依赖这里用的gradle,仓库地址可以去dubbo仓库地址查看
1
compile group: 'com.alibaba', name: 'dubbo', version: '2.6.1'
在
common_interface
项目中添加一个接口类1
2
3
4
5package exxk.dubbo.commonimpl;
public interface DemoService {
String sayHello(String name);
}在
provider
项目中实现DemoService
接口,在java目录下新建impl包,并添加一个DemoServiceImpl
实现类1
2
3
4
5
6
7
8
9
10package exxk.dubbo.provider.impl;
import exxk.dubbo.commonimpl.DemoService;
public class DemoServiceImpl implements DemoService{
public String sayHello(String name) {
return "hello"+ name;
}
}在
provider
项目中resource
目录下添加一个dubbo配置文件dubbo-provider.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--该提供者服务名称-->
<dubbo:application name="dubbo-provider"/>
<!--组播模式的注册中心,推荐用zookeeper-->
<dubbo:registry address="multicast://224.5.6.7:1234"/>
<!--暴露的端口服务-->
<dubbo:protocol name="dubbo" port="20880"/>
<!--声明暴露服务公共接口类-->
<dubbo:service interface="exxk.dubbo.commonimpl.DemoService" ref="demoService"/>
<!--提供者实现类-->
<bean id="demoService" class="exxk.dubbo.provider.impl.DemoServiceImpl"/>
</beans>在
provider
项目中java
目录下添加一个dubbo 启动类Provider.java
1
2
3
4
5
6
7
8
9
10
11
12
13package exxk.dubbo.provider;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Provider {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[]{"dubbo-provider.xml"}); //读取dubbo配置文件
context.start();
//按任何键推出
System.in.read();
}
}上面的服务提供者基本完成,然后启动服务提供者,直接运行
Provider.java
静态方法即可在
consumer
项目中resource
目录下添加一个dubbo配置文件dubbo-consumer.xml
1
2
3
4
5
6
7
8
9
10
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="dubbo-consumer"/>
<!--注册中心地址(多播)-->
<dubbo:registry address="multicast://224.5.6.7:1234"/>
<dubbo:reference id="demoService" interface="exxk.dubbo.commonimpl.DemoService"/>
</beans>在
consumer
项目中java
目录下添加一个dubbo 启动类Consumer.java
1 | package exxk.dubbo.consumer; |
- 启动
consumer
服务消费者项目,这里用debug模式运行Consumer.java
在里面打断点,主要是日志不好找,因此debug
基于springboot优化启动类
在springboot启动类添加dubbo启动,去掉默认的dubbo启动
最直接的是把dubbo启动类的配置xml内容直接放到application启动类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[]{"dubbo-provider.xml"}); //读取dubbo配置文件
context.start();
//同步锁,保持该线程一直运行
synchronized (Provider.class){
while(true){
try {
Provider.class.wait();
}catch (Exception e){
System.out.print("synchronized===:"+e);
}
}
}
}
}这种当然不优雅,可以直接把xml配置文件配置到注解
@ImportResource
上1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
//同步锁,保持该线程一直运行
synchronized (Provider.class){
while(true){
try {
Provider.class.wait();
}catch (Exception e){
System.out.print("synchronized===:"+e);
}
}
}
}
}代码是少了,但是据说,dubbo包含web框架,会让springboot当成web程序运行,这里自定义
SpringApplicationBuilder
禁用web1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ProviderApplication {
public static void main(String[] args) {
ApplicationContext context= new SpringApplicationBuilder()
.sources(ProviderApplication.class)
.web(WebApplicationType.NONE) //禁用web服务
.run(args);
//同步锁,保持该线程一直运行
synchronized (Provider.class){
while(true){
try {
Provider.class.wait();
}catch (Exception e){
System.out.print("synchronized===:"+e);
}
}
}
}
}同步锁线程也换种方式实现,利用同步工具类
CountDownLatch
,该工具类的大概作用就是有等待指定线程(数)执行完了,再执行1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ProviderApplication {
public CountDownLatch closeLatch() {
return new CountDownLatch(1);
}
public static void main(String[] args) throws InterruptedException {
//SpringApplication.run(ProviderApplication.class, args);
ApplicationContext context= new SpringApplicationBuilder()
.sources(ProviderApplication.class)
.web(WebApplicationType.NONE) //禁用web服务
.run(args);
CountDownLatch closeLatch=context.getBean(CountDownLatch.class);
closeLatch.await(); //等待所有子线程完成
}
}最后删除旧的启动器,到此大功告成