HttpServer服务类

 1 package javax.servlet.http.server2;
 2
 3 import java.io.IOException;
 4 import java.net.InetSocketAddress;
 5 import java.nio.channels.SelectionKey;
 6 import java.nio.channels.Selector;
 7 import java.nio.channels.ServerSocketChannel;
 8 import java.util.Iterator;
 9
10 public class HttpServer {
11     private int DEFULT_PORT=8080;               //默认端口
12     private boolean isShudown=true;            //服务状态
13     private ServerSocketChannel ssc;
14     public HttpServer(){
15         try{
16             start(DEFULT_PORT);
17         } catch (IOException e){
18             e.printStackTrace();
19         }
20     }
21
22     public HttpServer(int port){
23         try{
24             start(port);
25         } catch (IOException e){
26             e.printStackTrace();
27         }
28     }
29     public void start(int port) throws IOException{
30         ssc=ServerSocketChannel.open(); // 打开服务器套接字通道
31         ssc.socket().bind(new InetSocketAddress(port));     //绑定到特定端口
32         ssc.configureBlocking(false);                      //设置为非阻塞模式
33         Selector selector=Selector.open();                 //打开一个选择器
34         ssc.register(selector, SelectionKey.OP_ACCEPT);    //向给定的选择器注册此通道,返回一个选择键
35         while(isShudown){
36             /*if(selector.select(3000)==0){         //没有请求阻塞3秒,继续执行
37                 continue;
38             }*/
39             if(selector.select()>0){        //等待请求,请求过来继续执行,没有请求一直等待
40                 Iterator<SelectionKey> keyIter=selector.selectedKeys().iterator();          //获取等待处理的请求
41                 while (keyIter.hasNext()){
42                     SelectionKey key=keyIter.next();
43                     new Thread(new HttpHandler(key)).run();                    // 启动新线程处理SelectionKey
44                     keyIter.remove();                                           // 处理完后,从待处理的SelectionKey迭代器中移除当前所使用的key
45                }
46             }
47
48         }
49     }
50
51     /**
52      * 关闭端口
53      * @throws IOException
54      */
55     public void stop() throws IOException{
56         isShudown=false;
57         //ssc.socket().close();
58     }
59
60     /**
61      * 打开服务的主入口
62      * @param args
63      * @throws Exception
64      */
65     public static void main(String[] args) throws Exception{
66
67         new HttpServer(2222);
68     }
69
70
71 }

HttpHandler请求处理类

 1 package javax.servlet.http.server2;
 2
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 import java.io.StringWriter;
 6 import java.nio.ByteBuffer;
 7 import java.nio.channels.SelectionKey;
 8 import java.nio.channels.ServerSocketChannel;
 9 import java.nio.channels.SocketChannel;
10
11 public class HttpHandler implements Runnable{
12     private int bufferSize = 1024;
13     private SelectionKey key;
14     private int CODE=200;
15     public HttpHandler(SelectionKey key){
16         this.key = key;
17     }
18
19     /**
20      * 接收连接处理
21      * @throws IOException
22      */
23     public void handleAccept() throws IOException {
24         SocketChannel clientChannel=((ServerSocketChannel)key.channel()).accept();
25         clientChannel.configureBlocking(false);     //线程不阻塞
26         clientChannel.register(key.selector(), SelectionKey.OP_READ|SelectionKey.OP_WRITE, ByteBuffer.allocate(bufferSize));       //注册读写
27
28     }
29     @Override
30     public void run()
31     {
32         // 接收到连接请求时
33         if (key.isAcceptable())
34         {
35             try
36             {
37                 handleAccept();
38             } catch (IOException e)
39             {
40                 e.printStackTrace();
41             }
42
43         }
44
45         if (key.isReadable()&&key.isWritable())   //可读可写
46         {
47             try
48             {
49                 HttpServletRequest ser=new HttpServletRequest(key);                //封装Request
50                 HttpServletResponse serr=new HttpServletResponse(key);             //封装Response
51                 HttpServlet servlet=WebApp.getServlet(ser.getUrl());               //通过映射地址获取具体的servlet
52                 if(servlet==null){
53                     this.CODE=404;
54                 }else{
55                     try
56                     {
57                         servlet.service(ser, serr);
58                     } catch (Exception e)
59                     {
60                         e.printStackTrace();
61                         this.CODE=500;
62                         StringWriter sw = new StringWriter();
63                         PrintWriter pw = new PrintWriter(sw, true);
64                         pw.flush();
65                         sw.flush();
66                         serr.println(sw.toString());
67                     }
68                 }
69                 serr.pushToClient(CODE);
70                 ser.close();
71                 serr.close();
72             } catch (IOException e)
73             {
74                 e.printStackTrace();
75             }
76
77         }
78
79
80     }
81 }

HttpServlet基类

 1 package javax.servlet.http.server2;
 2
 3 public abstract class HttpServlet {
 4     public void service(HttpServletRequest req,HttpServletResponse rep) throws Exception{
 5         this.doGet(req,rep);
 6     }
 7
 8     protected  abstract void doGet(HttpServletRequest req,HttpServletResponse rep) throws Exception;
 9     protected  abstract void doPost(HttpServletRequest req,HttpServletResponse rep) throws Exception;
10 }

HttpServletRequest请求封装类

  1 package javax.servlet.http.server2;
  2
  3 import java.io.IOException;
  4 import java.nio.ByteBuffer;
  5 import java.nio.channels.SelectionKey;
  6 import java.nio.channels.SocketChannel;
  7 import java.nio.charset.Charset;
  8 import java.util.ArrayList;
  9 import java.util.Arrays;
 10 import java.util.HashMap;
 11 import java.util.List;
 12 import java.util.Map;
 13 import java.util.StringTokenizer;
 14
 15 public class HttpServletRequest
 16 {
 17     private final String DEFULT_CODE="UTF-8";
 18     private final String CRLF="\r\n";      //回车换行
 19     private final String SPACE=" ";
 20     private SocketChannel sc;
 21     private ByteBuffer buffer;
 22     private String requestInfo;
 23     private String method;
 24     private String url;
 25     private Map<String,List<String>> parameterMapValues;
 26
 27     public HttpServletRequest(){
 28         parameterMapValues=new HashMap<String,List<String>>();
 29     }
 30     public HttpServletRequest(SelectionKey key) throws IOException{
 31         this();
 32         sc=(SocketChannel)key.channel();
 33         buffer=(ByteBuffer)key.attachment();
 34         buffer.clear();
 35         if(sc.read(buffer)==-1){
 36              sc.close();
 37         }else{
 38              buffer.flip();
 39              requestInfo=Charset.forName(DEFULT_CODE).newDecoder().decode(buffer).toString();
 40         }
 41          parseRequestInfo();
 42     }
 43
 44     /**
 45      * 分析请求,主要是获取资源地址、封装专递的参数
 46      */
 47     private void parseRequestInfo(){
 48         String paramInfo = null;
 49         if(requestInfo==null||"".equals(requestInfo)){
 50             return ;
 51         }
 52         String[] requestMessage = requestInfo.split(CRLF);        //得到请求的消息
 53         String[] firstLine = requestMessage[0].split(SPACE);      //获取首行头文件
 54         this.method=firstLine[0];                  //获取提交方式
 55         String tempUrl=firstLine[1];               //获取资源地址
 56         if(method.equals(RequestType.POST.toString())){
 57             this.url=tempUrl;
 58             paramInfo=requestMessage[requestMessage.length-1];
 59         }else if(method.equals(RequestType.GET.toString())){
 60             if(tempUrl.contains("?")){       //如果有参数
 61                 String params[]=tempUrl.split("\\?");
 62                 this.url=params[0];
 63                 paramInfo=params[1];//接收请求参数
 64             }else
 65                 this.url=tempUrl;
 66         }
 67
 68         if(paramInfo==null||"".equals(paramInfo)){
 69             return ;
 70         }else
 71             parseParams(paramInfo);
 72     }
 73
 74     /**
 75      * 保存传递的参数
 76      * @param paramInfo
 77      */
 78     private void parseParams(String paramInfo){
 79         StringTokenizer token=new StringTokenizer(paramInfo,"&");
 80         while(token.hasMoreTokens()){
 81             String keyValue =token.nextToken();
 82             String[] keyValues=keyValue.split("=");
 83             if(keyValues.length==1){
 84                 keyValues =Arrays.copyOf(keyValues, 2);
 85                 keyValues[1] =null;
 86             }
 87
 88             String key = keyValues[0].trim();
 89             String value = null==keyValues[1]?null:keyValues[1].trim();
 90             //转换成Map 分拣
 91             if(!parameterMapValues.containsKey(key)){
 92                 parameterMapValues.put(key,new ArrayList<String>());
 93             }
 94
 95             List<String> values =parameterMapValues.get(key);
 96             values.add(value);
 97         }
 98     }
 99
100     /**
101      * 根据页面的name 获取对应的多个值
102      * @param name   名
103      */
104     public String[] getParameterValues(String name){
105         List<String> values=null;
106         if((values=parameterMapValues.get(name))==null){
107             return null;
108         }else{
109             return values.toArray(new String[]{});
110         }
111     }
112
113     /**
114      * 返回单个值
115      * @param name 名
116      * @return
117      */
118     public String getParameter(String name){
119         String[] values =getParameterValues(name);
120         if(null==values){
121             return null;
122         }
123         return values[0];
124     }
125
126     /**
127      * 获取请求方法
128      * @return
129      */
130     public String getMethod()
131     {
132         return method;
133     }
134
135     /**
136      * 获取url资源访问地址
137      * @return
138      */
139     public String getUrl()
140     {
141         return url;
142     }
143     /**
144      * 关闭连接
145      */
146      void close()
147     {
148         try
149         {
150             if (sc.isOpen())
151             {
152                 sc.close();
153             }
154         } catch (IOException e)
155         {
156             e.printStackTrace();
157         }
158     }
159 }

HttpServletResponse响应封装类

  1 package javax.servlet.http.server2;
  2
  3 import java.io.IOException;
  4 import java.nio.ByteBuffer;
  5 import java.nio.channels.SelectionKey;
  6 import java.nio.channels.SocketChannel;
  7 import java.util.Date;
  8 public class HttpServletResponse
  9 {
 10
 11     //两个常量
 12     public static final String CRLF="\r\n";
 13     public static final String BLANK=" ";
 14     private static final String localCharset="UTF-8";
 15     //正文
 16     private StringBuilder content;
 17     //存储头信息
 18     private StringBuilder headInfo;
 19     //存储正文长度
 20     private int len =0;
 21     private StringBuilder bu;
 22     private ByteBuffer buffer;
 23     private SocketChannel sc;
 24     public HttpServletResponse(){
 25         bu=new StringBuilder();
 26         headInfo =new StringBuilder();
 27         content =new StringBuilder();
 28         len =0;
 29     }
 30     public HttpServletResponse(SelectionKey key){
 31         this();
 32         sc=(SocketChannel)key.channel();
 33         buffer=(ByteBuffer)key.attachment();
 34         buffer.clear();
 35         buffer.flip();
 36     }
 37
 38     /**
 39      * 构建正文
 40      */
 41     public HttpServletResponse print(String info){
 42         content.append(info);
 43         len+=info.getBytes().length;
 44         return this;
 45     }
 46
 47     /**
 48      * 构建正文+回车
 49      */
 50     public HttpServletResponse println(String info){
 51         content.append(info).append(CRLF);
 52         len+=(info+CRLF).getBytes().length;
 53         return this;
 54     }
 55
 56     /**
 57      * 构建响应头
 58      */
 59     private void createHeadInfo(int code){
 60         //1)  HTTP协议版本、状态代码、描述
 61         headInfo.append("HTTP/1.1").append(BLANK).append(code).append(BLANK);
 62         switch(code){
 63             case 200:
 64                 headInfo.append("OK");
 65                 break;
 66             case 404:
 67                 headInfo.append("NOT FOUND");
 68                 break;
 69             case 505:
 70                 headInfo.append("SEVER ERROR");
 71                 break;
 72         }
 73         headInfo.append(CRLF);
 74         //2)  响应头(Response Head)
 75         headInfo.append("Server:bjsxt Server/0.0.1").append(CRLF);
 76         headInfo.append("Date:").append(new Date()).append(CRLF);
 77         headInfo.append("Content-type:text/html;charset="+localCharset).append(CRLF);
 78         //正文长度 :字节长度
 79         headInfo.append("Content-Length:").append(len).append(CRLF);
 80         headInfo.append(CRLF); //分隔符
 81     }
 82
 83     //推送到客户端
 84     void pushToClient(int code) throws IOException{
 85             if(null==headInfo){
 86                 code =500;
 87             }
 88             createHeadInfo(code);
 89             //头信息+分割符
 90             bu.append(headInfo.toString());
 91
 92             //正文
 93             bu.append(content.toString());
 94             buffer = ByteBuffer.wrap(bu.toString().getBytes(localCharset));
 95             if(sc.isOpen())
 96                 sc.write(buffer);
 97
 98         }
 99
100     /**
101      * 关闭
102      */
103     void close(){
104         try
105         {
106             if(sc.isOpen()){
107                 sc.close();
108             }
109
110         } catch (IOException e)
111         {
112             e.printStackTrace();
113         }
114     }
115 }

RequestType请求类型

1 package javax.servlet.http.server2;
2
3 public enum RequestType
4 {
5 POST    //post请求
6 ,GET    //get请求
7
8 }

ServletContext 容器

 1 package javax.servlet.http.server2;
 2
 3 import java.util.HashMap;
 4 import java.util.Map;
 5
 6
 7 public class ServletContext
 8 {
 9
10     private Map<String,String>servlet;
11     public ServletContext(){
12         servlet=new HashMap<String,String>();
13     }
14
15     /**
16      * 获取servlet容器
17      * @return
18      */
19     public Map<String, String> getServlet()
20     {
21         return servlet;
22     }
23
24 }

WebApp功能映射处理

 1 package javax.servlet.http.server2;
 2
 3 import java.util.Iterator;
 4 import java.util.Map;
 5 import javax.servlet.annotation.WebServlet;
 6 import javax.servlet.util.PackageScanUtils;
 7
 8 public class WebApp
 9 {
10
11     private static ServletContext context;
12     static{
13         context=new ServletContext();
14         Map<String,String>servlet=context.getServlet();
15         Iterator<Class<?>>clas=PackageScanUtils.getClasses("javax.servlet.http.server2",true).iterator();
16         while(clas.hasNext()){
17             Class<?>cla=clas.next();
18             WebServlet ws=cla.getAnnotation(WebServlet.class);
19             if(ws!=null){
20                 servlet.put(ws.value(), cla.getName());
21             }
22         }
23     }
24
25     /**
26      * 获取url地址
27      * @param url
28      * @return
29      */
30     public static HttpServlet getServlet(String url)
31     {
32         Map<String,String>temp=context.getServlet();
33         if(temp.containsKey(url)){
34             try
35             {
36                 return (HttpServlet)Class.forName(temp.get(url)).newInstance();
37             } catch (InstantiationException e)
38             {
39                 e.printStackTrace();
40             } catch (IllegalAccessException e)
41             {
42                 e.printStackTrace();
43             } catch (ClassNotFoundException e)
44             {
45                 e.printStackTrace();
46             }
47         }
48         return null;
49     }
50 }

Message 状态

 1 package javax.servlet.cod;
 2
 3 public class Message
 4 {
 5
 6     public static String message404(){
 7         StringBuilder conetxt=new StringBuilder();
 8         conetxt.append("<html><head><title>lishenglin - Error report</title><style><!--H1");
 9         conetxt.append("{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2");
10         conetxt.append("{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3");
11         conetxt.append("{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY");
12         conetxt.append("{font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B");
13         conetxt.append("{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P");
14         conetxt.append("{font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR");
15         conetxt.append("{color : #525D76;}--></style> </head><body><h1>HTTP Status 404 - </h1><HR size=\"1\" noshade=\"noshade\"><p><b>type</b> Status");
16         conetxt.append("report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The requested resource is not available.</u></p><HR size=\"1\"");
17         conetxt.append("noshade=\"noshade\"><h3>lishenglin</h3></body></html>");
18         return conetxt.toString();
19
20     }
21
22 }

PackageScanUtils 扫描class

  1 package javax.servlet.util;
  2
  3 import java.io.File;
  4 import java.io.FileFilter;
  5 import java.io.FileNotFoundException;
  6 import java.io.IOException;
  7 import java.net.URL;
  8 import java.net.URLDecoder;
  9 import java.util.Enumeration;
 10 import java.util.Iterator;
 11 import java.util.LinkedHashSet;
 12 import java.util.Set;
 13
 14 public class PackageScanUtils
 15 {
 16
 17         /**
 18          * 获取class集合
 19          * @param packName         包名
 20          * @param scanSubdirectory  扫描子目录
 21          * @return
 22          */
 23     public static Set<Class<?>> getClasses(String packName,boolean scanSubdirectory)
 24     {
 25
 26         Set<Class<?>> classes = new LinkedHashSet<Class<?>>(); // 装载class集合
 27         String packageName = packName; // 获取包的名字 并进行替换
 28         String packageUrlName = packageName.replace('.', '/');
 29         Enumeration<URL> urls; // 定义一个枚举的集合 并进行循环来处理这个目录下的class
 30         try
 31         {
 32             urls = Thread.currentThread().getContextClassLoader().getResources(packageUrlName);
 33
 34             // 循环迭代下去
 35             while (urls.hasMoreElements())
 36             {
 37
 38                 URL url = urls.nextElement(); // 获取下一个元素
 39
 40                 String protocol = url.getProtocol(); // 得到协议的名称,比如http、file
 41
 42                 if ("file".equals(protocol))
 43                 { // 如果是以文件的形式保存在服务器上
 44
 45                     String filePath = URLDecoder.decode(url.getFile(), "UTF-8"); // 获取包的物理路径
 46                     // 以文件的方式扫描整个包下的文件 并添加到集合中
 47                     findClassesInPackageByFile(packageName, filePath, scanSubdirectory, classes);
 48                 }
 49             }
 50         } catch (IOException e)
 51         {
 52             e.printStackTrace();
 53          }
 54
 55         return classes;
 56     }
 57
 58     /**
 59      * 以文件的方式扫描整个包下的文件 并添加到集合中
 60      * @param packageName   包名
 61      * @param packagePath   包路径
 62      * @param scanSubdirectory     是否扫描子目录
 63      * @param classes        class集合
 64      * @throws FileNotFoundException
 65      */
 66     public static void findClassesInPackageByFile(String packageName, String packagePath, final boolean scanSubdirectory, Set<Class<?>> classes) throws FileNotFoundException
 67     {
 68
 69         File dir = new File(packagePath); // 获取此包的目录 建立一个File
 70         File[] dirfiles = dir.listFiles(new FileFilter()
 71         { // 如果存在 就获取包下的所有文件 包括目录
 72
 73             public boolean accept(File file)
 74             { // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
 75                 return (scanSubdirectory && file.isDirectory()) || (file.getName().endsWith(".class"));
 76             }
 77         });
 78
 79         for (File file : dirfiles)
 80         { // 循环所有文件
 81
 82             if (file.isDirectory())
 83             { // 如果是目录 则继续扫描
 84                 findClassesInPackageByFile(packageName==""? file.getName():packageName + "." + file.getName(), file.getAbsolutePath(), scanSubdirectory, classes);
 85             } else
 86             { // 如果是java类文件 去掉后面的.class 只留下类名
 87
 88                 String className = file.getName().substring(0, file.getName().length() - 6);
 89                 try
 90                 {
 91                     if("".equals(packageName)){
 92                         classes.add(Thread.currentThread().getContextClassLoader().loadClass(className));
 93                     }else{
 94                         classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));
 95                     }
 96                 } catch (ClassNotFoundException e)
 97                 {
 98                     e.printStackTrace();
 99                 }
100             }
101         }
102     }
103
104     public static void main(String[] args)
105     {
106         Set<Class<?>> clas=PackageScanUtils.getClasses("cn.javax",true);
107         Iterator<Class<?>>cla=clas.iterator();
108         while(cla.hasNext()){
109             /*Annotation[]ann=cla.next().getAnnotations();
110             for(Annotation a:ann){
111                 if(a instanceof WebServlet){
112                     System.out.println(((WebServlet) a).value());
113                 }
114             }*/
115             System.out.println(cla.next().getName());
116         }
117     }
118 }

MyServlet 测试servlet

 1 package javax.servlet.http.server2;
 2
 3 import javax.servlet.annotation.WebServlet;
 4
 5 @WebServlet("/myservlet")
 6 public class Myservlet extends HttpServlet
 7 {
 8
 9
10     @Override
11     protected void doGet(HttpServletRequest req, HttpServletResponse rep) throws Exception
12     {
13         this.doPost(req, rep);
14
15     }
16
17     @Override
18     protected void doPost(HttpServletRequest req, HttpServletResponse rep) throws Exception
19     {
20         String name=req.getParameter("name");
21         rep.println("获取的参数name="+name);
22         rep.println("请求的url是:"+req.getUrl());
23
24     }
25 }

WebServlet简单注解

 1 package javax.servlet.annotation;
 2
 3 import java.lang.annotation.ElementType;
 4 import java.lang.annotation.Retention;
 5 import java.lang.annotation.RetentionPolicy;
 6 import java.lang.annotation.Target;
 7
 8 @Target(ElementType.TYPE)
 9 @Retention(RetentionPolicy.RUNTIME)
10 /**
11  * webServlet注解
12  * @author 李圣霖
13  * @date 2017年3月28日
14  */
15 public abstract @interface WebServlet
16 {
17     public abstract java.lang.String value() default "";        //映射地址
18 }

测试

转载于:https://www.cnblogs.com/xysl/p/6656909.html

手写简单的HttpServer基于Java nio 实现socket异步通信(请求映射注解方式)相关推荐

  1. 基于Java NIO的Socket通信

    基于Java NIO的Socket通信 Java NIO模式的Socket通信,是一种同步非阻塞IO设计模式,它为Reactor模式实现提供了基础. 下面看看,Java实现的一个服务端和客户端通信的例 ...

  2. 基于 Java NIO 实现简单的 HTTP 服务器

    1.简介 本文是上一篇文章实践篇,在上一篇文章中,我分析了选择器 Selector 的原理.本篇文章,我们来说说 Selector 的应用,如标题所示,这里我基于 Java NIO 实现了一个简单的 ...

  3. java源码聊天软件_【原创】基于Java NIO的多人在线聊天工具源码实现(登录,单聊,群聊)...

    近来在学习Java NIO网络开发知识,写了一个基于Java NIO的多人在线聊天工具MyChat练练手.源码公开在Coding上: 编写一个基于Java NIO的多人在线聊天工具,需要以下几方面的知 ...

  4. 基于java nio的memcached客户端——xmemcached

    1.xmemcached是什么? xmemcached是基于java nio实现的memcached客户端API. 实际上是基于我实现的一个简单nio框架 http://code.google.com ...

  5. 并发型服务器响应方式,基于Java NIO 开发高性能并发型服务器程序的研究

    基于Java NIO 开发高性能并发型服务器程序的研究 第8卷%第5期 软件导刊 2009年5月SoftwareGuide Vol.8No.5May.2009 基于JavaNIO开发高性能并发型服务器 ...

  6. 手写简单的HashMap(jdk1.7)

    手写简单的HashMap(jdk1.7) public class MyHashMap<K, V> { //创建一个节点数组 private Entry1<K, V>[] ta ...

  7. 使用代理模式手写简单的数据库连接池

    使用代理模式手写简单的数据库连接池 JDBC直连数据库 思考 改造 ConnectionProxy ConnectionPool ProxyMain 运行结果 代理模式 与装饰器的区别 JDBC直连数 ...

  8. 第二季:5公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自旋锁【Java面试题】

    第二季:5值传递和引用传递[Java面试题] 前言 推荐 值传递 说明 题目 24 TransferValue醒脑小练习 第二季:5公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自 ...

  9. Dubbo——手写简单版Dubbo框架

    摘要 本博文将详细的介绍的一个手写简单版本的dubbo的实现. 项目架构原理图 项目源码实现 https://github.com/2462612540/DubboPrinciple/tree/mas ...

最新文章

  1. 多目标pareto最优解集构造方法
  2. 高压包输出信号经过整流后形成直流电流
  3. 火星坐标、百度坐标、WGS-84坐标相互转换及墨卡托投影坐标转经纬度JavaScript版...
  4. 网站栏目页要如何进行优化呢?
  5. map使用不存在的下标
  6. C++ 静态线性表的顺序存储结构(数组实现)
  7. 道理我都懂,但你到底为什么偏偏喜欢咬我??
  8. bioconductor 安装包_R语言 | 你知道自己的Bioconductor版本么?
  9. Android页面跳转、延时跳转、跳转传值
  10. 浅谈win10修复系统文件的方法
  11. 局域网中计算机与网线连接的设备是6,Cat5e、Cat6、Cat6a和Cat7网线有什么区别?...
  12. Soap+xml实现webservice 调用
  13. 计算机基础知识实验课教案,高职《计算机网络基础》实验课程教学设计
  14. 分布式调度框架大集合
  15. 机器人建模中移动关节如何建立坐标系_简述空间机器人运动学和动力学建模
  16. 智能窗帘传感器c语言程序,单片机智能家居电路控制程序+Proteus仿真+视频(光烟雾传感器与自动窗帘)...
  17. contiki编程(一)
  18. 追女生要经过哪几个阶段?告诉你追女生经历的具体阶段!
  19. git-bash.exe和git-cmd.exe运行Git的区别
  20. 谷歌浏览器在线安装下载的安装文件在哪里?

热门文章

  1. 大数据怎么学习:大数据学习的关键技术知识体系、学习路径和误区
  2. 超级搞笑~`记得转噢
  3. 博弈论题目总结(二)——SG组合游戏及变形
  4. 南北朝梁陶弘景撰《神农本草经集注》
  5. MTK功能机使用Catcher+PowerGPS调试GPS
  6. 赤月传说2如何修改服务器时间,9377赤月传说2 12月14日跨服开启公告
  7. lim sup和lim inf,上极限和下极限什么意思?
  8. Ubuntu Postgresql安装配置
  9. enq: SQ - contention
  10. 第五章:web服务器