Provider目录结构
1.服务端的启动
/**
* Created by cheng.xi on 2017-04-1410:25.
* 服务提供者端发布服务
* 可以使用API直接发布服务,也可以使用和Spring集成
* 这里是测试使用API发布服务
*/
public class TestApiProvider {
public static void main(String[] args) throws InterruptedException{
//要发布的服务
HelloWorldServicehelloWorldService = new HelloWorldServiceImpl();
//发布服务
DubboProvider dubboProvider = new DubboProvider();
//注入端口,实现类,接口
dubboProvider.setPort(3347);
dubboProvider.setRef(helloWorldService);
dubboProvider.setInterface(HelloWorldService.class);
//调用发布接口
dubboProvider.export();
}
}
2.服务的发布过程
进入到dubboProvider.export()方法内部看看里面都实现了什么
/** * 发布服务,每次只发布一个服务 */ public synchronized void export() throws InterruptedException { //调用协议层,根据具体协议暴露服务 Protocol protocol = MiniDubboProtocol.getMiniDubboProtocol(); protocol.export(this.interfaceName,this.ref.getClass()); //发布的服务缓存起来 }
再进去
protocol.export(this.interfaceName,this.ref.getClass());
public void export(String interfaceName, Class<?> impl) throws InterruptedException { //每个将每个接口的名字作为一个key,key用来作为对应实现的唯一键 String key = interfaceName; exportedServices.put(key,impl); //打开服务其进行监听 openServer(); System.out.println("minidubboprotocol中:" + exportedServices.size()); }
进入到openServer();
private void openServer() throws InterruptedException { //服务器监听地址 String address = "127.0.0.1"; //端口号 int port = 3347; //每个地址只打开一次 String key = address + ":" + port; Server server = serverMap.get(key); if(null == server){ //创建一个server serverMap.put(key,createServer(address,port)); } }
这里创建一个netty服务端,并绑定其提供者的实现
//创建server private Server createServer(String address, int port) throws InterruptedException { ChannelHandler handler = new NettyServiceHandler(exportedServices); Server server = Transporters.bind(address,port,handler); System.out.println("minidubboprotocol创建完server后:" + exportedServices.size()); return server; }
Netty服务端Handler
可以看到请求的接口名,方法名,参数都被封装到了request类中,并通过网络传输到netty的服务端,然后使用反射执行调用的方法,把执行的结果返回给客户端(关于netty大家可以多看看《netty实战》)
public class NettyServiceHandler extends SimpleChannelInboundHandler implements ChannelHandler{ private Map<String, Class<?>> exportedServices; public NettyServiceHandler(Map<String, Class<?>> exportedServices) { this.exportedServices = exportedServices; } protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object object) throws Exception { System.out.println("handler中exportedServices:" + exportedServices.size()); Request request = (Request)object; String serviceName = request.getInterfaceName(); String methodName = request.getMethodName(); Class<?>[] parameterTypes = request.getParameterTypes(); Object[] arguments = request.getArgs(); Class serviceClass = exportedServices.get(serviceName); Method method = serviceClass.getMethod(methodName,parameterTypes); Object result = method.invoke(serviceClass.newInstance(),arguments); Response response = new Response(); response.setResult(result); channelHandlerContext.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } }
至于netty服务的启动看代码Server server = Transporters.bind(address,port,handler);
//绑定,监听 public static Server bind(String address, int port, ChannelHandler handler) throws InterruptedException { Server server = new NettyServer(address,port,handler); return server; }
public class NettyServer implements Server{ private String address; private int port; private ChannelHandler handler; public NettyServer(String address, int port, ChannelHandler handler) throws InterruptedException { this.address = address; this.port= port; this.handler = handler; doOpen(); } public void doOpen() throws InterruptedException { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try{ ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup,workerGroup); serverBootstrap.channel(NioServerSocketChannel.class); serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() { protected void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline pipeline = socketChannel.pipeline(); pipeline.addLast(new ObjectDecoder(1024*1024, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader()))); pipeline.addLast(new ObjectEncoder()); pipeline.addLast((SimpleChannelInboundHandler)handler); } }); serverBootstrap.option(ChannelOption.SO_BACKLOG,1024); serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE,true); ChannelFuture future = serverBootstrap.bind(address,port).sync(); //future.channel().closeFuture().sync(); }finally{ //workerGroup.shutdownGracefully(); //bossGroup.shutdownGracefully(); } } }
到这服务就启动起来了