Dubbo框架篇(三)----------Dubbo在工程中的实际应用

      之前我讲述了关于dubbo安装的一些基本的准备工作。之前也说过了,dubbo是一种远程服务调用。关于dubbo的底层原理,由于我是初学者的身份,在这里我也没有办法说明。但是根据我在网上的视频,我对dubbo在现在流行的工程框架中进行了部署和使用。这篇博客我就来讲述一下关于dubbo的具体使用。

   1.服务提供者的配置

      我们知道,在用户请求服务的时候,远程服务器的服务必须优先启动。那么首先我来讲述一下关于服务提供者的配置。

     在最初学习java的时候,我们都接触到了关于接口的编程。接口定义了一种规范,告诉实现代码的人应该完成什么样的工作, 

接口的定义有助于工程的维护和更新还有不同工作人员代码的整合。在声明服务之前,我打算将我的服务接口写出。由于是测试,我的服务写的很简单。就以我们在jdbc操作中初始化数据为例。

 首先新建一个java工程,在这里面声明一个接口如下所示

package com.lw.gmall.service;

public interface OrderService {
	public void initOrder(String id);
}

在服务提供者的工程中实现这个接口,注意要在服务提供者的工程中引入刚才的工程。在pom.xml文件中加入如下的依赖

 <dependency>
    	 <groupId>com.lw.gmall</groupId>
  <artifactId>dubbo-service-inter</artifactId>
  <version>0.0.1-SNAPSHOT</version>
    </dependency>

之后就是服务的实现,这些都不陌生。

package com.lw.gmall.service;

import java.util.Arrays;
import java.util.List;

import com.lw.gmall.entity.Address;

public class UserServiceImpl implements UserService{

	public List<Address> getAddressById(String id) {
		System.out.println("UserServiceImpl。。。。。1");
		Address a1 = new Address(id,"河南省新乡市");
		Address a2 = new Address(id,"河南省郑州市");
//		try {
//			Thread.sleep(4000);
//		} catch (InterruptedException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		return Arrays.asList(a1,a2);
	}
	
}

忽略掉注释的地方,那是之后关于服务超时的测试。关于服务的声明已经完成,接下来就是服务的配置了。这也是整个dubbo框架使用的核心。

首先指定服务的名称,这个只是作为一个标记

 <!-- 指定当前应用的名字 -->
    <dubbo:application name="dubbo-user-service-provider"></dubbo:application>

然后声明注册中心的位置,我的注册中心配置在了我的linux虚拟机上,使用的是zookeeper作为注册中心,zookeeper默认监听2181端口 

	<!-- 指定注册中心的位置 -->
    <dubbo:registry protocol="zookeeper" address="myhadoop:2181">
    </dubbo:registry>

接下里指定通信规则,名称是dubbo因为是dubbo的框架。后面的端口号是指服务发布/监听在20881端口下,这个端口对于一个工程中的服务只能部署一次。 

<!-- 指定通信规则 -->
    <dubbo:protocol name="dubbo" port="20081"></dubbo:protocol>

关于框架的基本服务配置完成后,接下来就是对服务进行暴露。 我声明了服务的版本号(默认是0.0.0)指明了服务的实现者

<!-- 将服务进行暴露 -->
    <dubbo:service version="1.0.0" interface="com.lw.gmall.service.UserService" ref="userServiceImpl"></dubbo:service>
   
   <bean id="userServiceImpl" class="com.lw.gmall.service.UserServiceImpl"></bean>
   
    </beans>

接下来我们就可以将我们的zookeeper进行启动了,启动的过程我之前的博客提到过。启动完成后,我们的服务就注册到了注册中心,只要将服务消费者进行配置注册,完整的功能模块就实现了。

2.服务消费者的配置

关于代码的实现和之前提供者的实现是类似的,我不再重复。

package com.lw.gmall.service;

import java.util.List;

import com.lw.gmall.entity.Address;

public interface UserService {
	public List<Address> getAddressById(String id);
	
}
package com.lw.gmall.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.lw.gmall.entity.Address;
@Service
public class OrderServiceImpl implements OrderService{
	@Autowired
	@Qualifier("userService")
	private UserService userService;
	public void initOrder(String id) {
		//调用用户服务
		
		List<Address> addressList = userService.getAddressById(id);
		for(Address address : addressList){
			System.out.println(address);
		}
	}
	
}

主要的难点是服务消费者的配置

<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="dubbo-order-service-consumer"  />
 
    <!-- 使用zookeeper注册中心暴露发现服务地址 -->
    <dubbo:registry address="zookeeper://myhadoop:2181" />

 这些和提供者也是类似的,配置到相应的zookeeper服务器上。

   <dubbo:reference 
 
   version="1.0.0"
    id="userService" 
    interface="com.lw.gmall.service.UserService" 
   
    
    >
    </dubbo:reference>

这是为了将相应的服务注入到容器中,这是在spring ioc容器中提到过的部分 

<!-- 扫描相应的包 -->
	<context:component-scan base-package="com.lw.gmall.service"></context:component-scan>

 这就是服务消费者的配置过程

3.过程分析

这里我声明了两个启动类

提供者

package com.lw.gmall;

import java.io.IOException;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApplication {

	public static void main(String[] args) throws IOException {
		ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("provider.xml");
		ioc.start();
		System.out.println("1号服务提供者启动");
		System.in.read();
	}

}

消费者

package com.lw.gmall;

import java.io.IOException;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lw.gmall.service.OrderService;
import com.lw.gmall.service.OrderServiceImpl;

public class MainApplication {

	public static void main(String[] args) throws IOException {
		ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("consumer.xml");
		OrderService orderService = ioc.getBean(OrderServiceImpl.class);
		for(int i=0;i<10;i++){
			orderService.initOrder("1");
		}
		System.out.println("That is all");
		System.in.read();
	}

}

在首先启动提供者然后启动消费者后,可以控制台打印出了相应的结果。在实现了一系列的工作之后,我想分析一下服务的整个流程(当然是我自己根据测试结果的理解)

首先服务进行注册,也就是com.lw.gmall.service.UserService——>com.lw.gmall.service.UserServiceImpl。它的版本号是1.0.0

消费者在进行消费时,它会查找和它版本号相同的服务,于是就找到了我们之前的配置。

这里可以进行代码的参考。

<!-- 将服务进行暴露 -->
    <dubbo:service version="1.0.0" interface="com.lw.gmall.service.UserService" ref="userServiceImpl"></dubbo:service>
   
   <bean id="userServiceImpl" class="com.lw.gmall.service.UserServiceImpl"></bean>
   
    </beans>
  <dubbo:reference 
   version="1.0.0"
    id="userService" 
    interface="com.lw.gmall.service.UserService" 
    > </dubbo:reference>

回到消费者的服务调用代码中,关于userService的实现我做了如下的声明。

@Autowired
	@Qualifier("userService")
	private UserService userService;

这就是ioc容器的依赖注入,可以看到Qualifier注解中的userService也和dubbo:reference的服务引用中的id保持了一致。这样userService就实现了服务的注入。实际上它指向的是(远程的)的服务提供者。

4.dubbo和springboot的整合

刚才都只是dubbo的测试,那么如何才能将duboo和springboot进行整合呢。其实很简单,原理都是相同的,只是有一些部分需要根据springboot的特性进行处理。

引入如下的依赖。

<dependency>
			<groupId>com.alibaba.boot</groupId>
			<artifactId>dubbo-spring-boot-starter</artifactId>
			<version>0.2.0</version>
		</dependency>

服务的声明如下所示,这里有些需要强调的地方 首先@Service是import com.alibaba.dubbo.config.annotation.Service;这个非常重要,其次我在@Component中声明的AreYouOK一会也有别的用途

package com.lw.gmall.service;

import java.util.Arrays;
import java.util.List;

import org.springframework.stereotype.Component;

import com.alibaba.dubbo.config.annotation.Service;
import com.lw.gmall.entity.Address;
import com.lw.gmall.service.UserService;


@Service() //将服务进行暴露
@Component("AreYouOk")

public class UserServiceImpl implements UserService{

	public List<Address> getAddressById(String id) {
		Address a1 = new Address(id,"河南省新乡市");
		Address a2 = new Address(id,"河南省郑州市");
		return Arrays.asList(a1,a2);
	}
	
}

在springboot的启动类中加入@EnableDubbo注解开启服务即可。 

package com.lw.gmall;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
@EnableDubbo
@SpringBootApplication
public class SpringBootOrderServiceConsumerApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootOrderServiceConsumerApplication.class, args);
	}

}

至于消费者的部分,有很多和提供者相似。我只提提重点的部分即可。其中的@Reference和dubbo:reference相同。它指向了服务的所在。至于下方的@Qualifier("AreYouOk")和上面的也进行了对应。当然这只是测试。我的建议是根据version也就是版本号实现服务的统一。

package com.lw.gmall.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.lw.gmall.entity.Address;
import com.lw.gmall.service.OrderService;
import com.lw.gmall.service.UserService;
@Service
public class OrderServiceImpl implements OrderService{
	@Reference()
	@Qualifier("AreYouOk")
	private UserService userService;
	public void initOrder(String id) {
		//调用用户服务
		List<Address> addressList = userService.getAddressById(id);
		for(Address address : addressList){
			System.out.println(address);
		}
	}
	
}

在启动完成之后同样实现了相同的效果。下一次我将深入讲述dubbo的用户文档,也就是关于dubbo配置的详细信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值