Dubbo是微服务框架,服务需要部署到不同JVM虚拟机,由此代理的问题是需要提供一个统一Jar包(包含Dubbo接口和JVM间传递的实体类),Dubbo服务器端与客户端需要共享这个Jar包,在项目开发中这是最为通用的方法,
但在Dubbo案例中如此实现,需要定义三个Maven工程,工作量很大,如下方案实现类在一个SpringBoot项目中启动Dubbo服务端和Dubbo客户端,避免共享Jar带来的问题
实现思路如下:
提供两个SpringBoot启动类,一个启动Dubbo服务,另一个启动Dubbo客户端,启动Dubbo服务的类,使用代码修改server.port端口,并且自动扫描包路径中,不扫描Controller所在包;Dubbo客户端启动类,使用配置文件application.properties中定义的端口,并且SpringBoot启动时排除RabbitMQ自动配置,包扫描路径只配置Controller所在包。
启动Dubbo服务器启动类
package com.test;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
@SpringBootApplication
@EnableDubboConfiguration
//只扫描工具类所在包和服务实现类所在包,排除Controller所在包的扫描
@ComponentScan("com.test.util,com.test.service.impl")
public class DubboServer extends SpringBootServletInitializer
{
public static void main( String[] args )
{
//使用代码修改server.port端口
System.setProperty("server.port","6070");
SpringApplication.run(DubboServer.class,args);
}
}
启动Dubbo客户端启动类
package com.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
import com.test.util.RabbitmqListener;
import org.springframework.context.annotation.FilterType;
//SpringBoot启动排除RabbitMQ自动配置
@SpringBootApplication(exclude={RabbitAutoConfiguration.class})
@EnableDubboConfiguration
//只扫描Controller所在包
@ComponentScan("com.test.ctrl")
//@ComponentScan(basePackages={"com.test.util"},excludeFilters={@ComponentScan.Filter(type=FilterType.ANNOTATION, value=Component.class)})
public class Starter
{
public static void main( String[] args )
{
SpringApplication.run(Starter.class,args);
}
}
Dubbo服务实现类
ServiceImpl.java
package com.test.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.test.mapper.OrderMapper;
import com.test.model.AddressInfo;
import com.test.model.OrderInfo;
import com.test.model.OrderItemInfo;
import com.test.service.IDaoService;
import com.test.service.IService;
import com.test.util.IMsgProcess;
import com.test.util.SendMsg;
@com.alibaba.dubbo.config.annotation.Service(interfaceClass=IService.class)
@Service
public class ServiceImpl implements IService,IMsgProcess{
@Autowired
private IDaoService dao;
@Autowired
private SendMsg sendmsg;
public Map getOrder(Integer page,Integer rows)
{
PageHelper.startPage(page,rows);
List<OrderInfo> list = dao.findOrder();
PageInfo pi = new PageInfo(list);
Long total = pi.getTotal();
List<OrderInfo> orders = pi.getList();
Map m = new HashMap();
m.put("total", total);
m.put("orders", orders);
return m;
}
/**
* 订单Controller远程调用的方法
* @param oi 包含订单主表信息和明细表信息
* @return
*/
@Override
public boolean saveOrder(OrderInfo oi) {
System.out.println("ServiceImpl.saveOrder oi="+oi);
List<OrderItemInfo> items = oi.getItems();
System.out.println("ServiceImpl.saveOrder items="+items);
//订单主表数据
dao.saveOrder(oi);
for(OrderItemInfo item:items)
{
item.setOrder_id(oi.getOrder_id());
Integer price = item.getItem_price();
Integer num = item.getItem_num();
item.setTotal_fee(price*num);
//订单明细表数据
dao.saveOrderItem(item);
}
//发送消息
oi.setItems(items);
sendmsg.sendObject(oi, 1);
return true;
}
@Override
public boolean updateStore(OrderInfo oi) {
System.out.println("ServiceImpl.updateStore oi="+oi);
List<OrderItemInfo> items = oi.getItems();
for(OrderItemInfo item:items)
{
System.out.println("ServiceImpl.updateStore item="+item);
dao.updateStore(item);
}
return false;
}
@Override
public Boolean process(Object obj) {
if(obj instanceof OrderInfo)
{
OrderInfo oi = (OrderInfo)obj;
updateStore(oi);
}
return true;
}
@Override
public List<AddressInfo> findProvince() {
return dao.findProvince();
}
@Override
public List<AddressInfo> findCityByPrvnc(String code) {
return dao.findCityByPrvnc(code);
}
@Override
public List<AddressInfo> findCountyByCity(String cityCode) {
return dao.findCountyByCity(cityCode);
}
}
Dubbo客户端Controller