├── .gitignore ├── README.md ├── code-ioc ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ ├── demo │ │ ├── IUserService.java │ │ ├── LogService.java │ │ ├── MainTest.java │ │ └── UserService.java │ │ └── ioc │ │ ├── annotation │ │ ├── MyAutowired.java │ │ └── MyComponent.java │ │ └── core │ │ └── MyIoc.java │ └── resources │ └── ioc.properties ├── code-netty-tomcat ├── README.md ├── img │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.png │ ├── 4.png │ └── 5.jpg ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ ├── catalina │ │ ├── config │ │ │ └── Config.java │ │ ├── http │ │ │ ├── Request.java │ │ │ ├── Response.java │ │ │ └── Servlet.java │ │ ├── server │ │ │ ├── BootStrap.java │ │ │ ├── Tomcat.java │ │ │ └── TomcatHandler.java │ │ └── servlet │ │ │ └── TestServlet.java │ │ └── hot │ │ ├── FileMonitor.java │ │ └── MyClassLoader.java │ └── resources │ └── web.properties ├── code-netty ├── README.md ├── img │ ├── 1.jpg │ └── 2.jpg ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── demo │ │ ├── ClientStart.java │ │ ├── ServerStart.java │ │ ├── bootstrap │ │ └── ServerBootstrap.java │ │ └── channel │ │ ├── AbstractNioSelector.java │ │ ├── IBoss.java │ │ ├── IWorker.java │ │ ├── NioSelectorRunnablePool.java │ │ ├── NioServerBoss.java │ │ └── NioServerWorker.java │ └── resources │ └── config.properties ├── code-proxy ├── README.md ├── img │ ├── 1.png │ └── 2.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ ├── IUserService.java │ ├── UserService.java │ ├── cglib │ └── CglibTest.java │ ├── jdk │ └── JdkTest.java │ └── my │ ├── $ProxyMy.java │ ├── MyClassLoader.java │ ├── MyInvocationHandler.java │ ├── MyProxy.java │ └── MyTest.java ├── code-redis ├── README.md ├── img │ ├── 1.jpg │ ├── 2.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ └── 9.png ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── demo │ ├── JedisTest.java │ ├── MyRedisService.java │ ├── command │ ├── EXITCommand.java │ ├── GETCommand.java │ ├── HGETCommand.java │ ├── HSETCommand.java │ ├── ICommand.java │ ├── INFOCommand.java │ ├── LPOPCommand.java │ ├── LPUSHCommand.java │ ├── LRANGECommand.java │ ├── PINGCommand.java │ ├── SADDCommand.java │ ├── SCARDCommand.java │ ├── SELECTCommand.java │ └── SETCommand.java │ ├── data │ ├── DbData.java │ └── PermanentData.java │ ├── exception │ └── RedisException.java │ └── procotol │ ├── MyDecode.java │ ├── ProtocolInputStream.java │ └── Protocolcode.java ├── code-springaop ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ ├── aop │ │ ├── MainTest.java │ │ ├── annotation │ │ │ ├── AdviceEnum.java │ │ │ ├── MyAfter.java │ │ │ ├── MyAfterReturning.java │ │ │ ├── MyAfterThrowing.java │ │ │ ├── MyAround.java │ │ │ ├── MyAspect.java │ │ │ ├── MyBefore.java │ │ │ └── MyPointcut.java │ │ ├── aspect │ │ │ ├── AbstractAspect.java │ │ │ ├── AspectHandler.java │ │ │ ├── CheckResult.java │ │ │ ├── IAspectHandler.java │ │ │ └── JoinPoint.java │ │ └── core │ │ │ ├── AopBeanContext.java │ │ │ ├── BeanInvocationHandler.java │ │ │ └── ProxyBeanFactory.java │ │ ├── demo │ │ ├── Aspect.java │ │ ├── IUserService.java │ │ └── UserService.java │ │ └── demo1 │ │ ├── ILogService.java │ │ ├── LogAspect.java │ │ └── LogService.java │ └── resources │ └── ioc.properties ├── pom.xml ├── study-algorithm ├── README.MD ├── pom.xml └── src │ └── main │ └── java │ └── com │ ├── demo │ ├── array │ │ └── package-info.java │ ├── graph │ │ └── package-info.java │ ├── hash │ │ └── package-info.java │ ├── heap │ │ └── package-info.java │ ├── list │ │ └── package-info.java │ ├── queue │ │ └── package-info.java │ ├── stack │ │ └── package-info.java │ ├── string │ │ ├── DelStr.java │ │ └── StrReverse.java │ └── tree │ │ └── package-info.java │ ├── sort │ ├── BubbleSort.java │ ├── InsertSort.java │ ├── QuickSort.java │ └── SelectionSort.java │ └── topk │ └── TopK.java ├── study-cache ├── README.MD ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── demo │ ├── ICache.java │ ├── MyCache.java │ └── MyCacheTest.java ├── study-chat ├── README.md ├── img │ ├── 1.jpg │ └── 2.jpg ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── demo │ │ ├── client │ │ ├── ChatClient.java │ │ └── ChatClientHandler.java │ │ ├── processor │ │ └── MsgProcessor.java │ │ ├── protocol │ │ ├── IMDecoder.java │ │ ├── IMEncoder.java │ │ ├── IMMessage.java │ │ └── IMP.java │ │ └── server │ │ ├── ChatServer.java │ │ └── handler │ │ ├── HttpHandler.java │ │ ├── SocketHandler.java │ │ └── WebSocketHandler.java │ └── resources │ ├── web.properties │ └── webroot │ ├── chat.html │ ├── css │ └── style.css │ ├── images │ ├── face │ │ ├── 1.gif │ │ ├── 10.gif │ │ ├── 100.gif │ │ ├── 101.gif │ │ ├── 102.gif │ │ ├── 103.gif │ │ ├── 104.gif │ │ ├── 105.gif │ │ ├── 106.gif │ │ ├── 107.gif │ │ ├── 108.gif │ │ ├── 109.gif │ │ ├── 11.gif │ │ ├── 110.gif │ │ ├── 111.gif │ │ ├── 112.gif │ │ ├── 113.gif │ │ ├── 114.gif │ │ ├── 115.gif │ │ ├── 116.gif │ │ ├── 117.gif │ │ ├── 118.gif │ │ ├── 119.gif │ │ ├── 12.gif │ │ ├── 120.gif │ │ ├── 121.gif │ │ ├── 122.gif │ │ ├── 123.gif │ │ ├── 124.gif │ │ ├── 125.gif │ │ ├── 126.gif │ │ ├── 127.gif │ │ ├── 128.gif │ │ ├── 129.gif │ │ ├── 13.gif │ │ ├── 130.gif │ │ ├── 14.gif │ │ ├── 15.gif │ │ ├── 16.gif │ │ ├── 17.gif │ │ ├── 18.gif │ │ ├── 19.gif │ │ ├── 2.gif │ │ ├── 20.gif │ │ ├── 21.gif │ │ ├── 22.gif │ │ ├── 23.gif │ │ ├── 24.gif │ │ ├── 25.gif │ │ ├── 26.gif │ │ ├── 27.gif │ │ ├── 28.gif │ │ ├── 29.gif │ │ ├── 3.gif │ │ ├── 30.gif │ │ ├── 31.gif │ │ ├── 32.gif │ │ ├── 33.gif │ │ ├── 34.gif │ │ ├── 35.gif │ │ ├── 36.gif │ │ ├── 37.gif │ │ ├── 38.gif │ │ ├── 39.gif │ │ ├── 4.gif │ │ ├── 40.gif │ │ ├── 41.gif │ │ ├── 42.gif │ │ ├── 43.gif │ │ ├── 44.gif │ │ ├── 45.gif │ │ ├── 46.gif │ │ ├── 47.gif │ │ ├── 48.gif │ │ ├── 49.gif │ │ ├── 5.gif │ │ ├── 50.gif │ │ ├── 51.gif │ │ ├── 52.gif │ │ ├── 53.gif │ │ ├── 54.gif │ │ ├── 55.gif │ │ ├── 56.gif │ │ ├── 57.gif │ │ ├── 58.gif │ │ ├── 59.gif │ │ ├── 6.gif │ │ ├── 60.gif │ │ ├── 61.gif │ │ ├── 62.gif │ │ ├── 63.gif │ │ ├── 64.gif │ │ ├── 65.gif │ │ ├── 66.gif │ │ ├── 67.gif │ │ ├── 68.gif │ │ ├── 69.gif │ │ ├── 7.gif │ │ ├── 70.gif │ │ ├── 71.gif │ │ ├── 72.gif │ │ ├── 73.gif │ │ ├── 74.gif │ │ ├── 75.gif │ │ ├── 76.gif │ │ ├── 77.gif │ │ ├── 78.gif │ │ ├── 79.gif │ │ ├── 8.gif │ │ ├── 80.gif │ │ ├── 81.gif │ │ ├── 82.gif │ │ ├── 83.gif │ │ ├── 84.gif │ │ ├── 85.gif │ │ ├── 86.gif │ │ ├── 87.gif │ │ ├── 88.gif │ │ ├── 89.gif │ │ ├── 9.gif │ │ ├── 90.gif │ │ ├── 91.gif │ │ ├── 92.gif │ │ ├── 93.gif │ │ ├── 94.gif │ │ ├── 95.gif │ │ ├── 96.gif │ │ ├── 97.gif │ │ ├── 98.gif │ │ └── 99.gif │ └── icon │ │ ├── face.png │ │ ├── file.png │ │ ├── flower.png │ │ └── img.png │ └── js │ ├── chat.util.js │ └── lib │ ├── jquery.min.js │ └── jquery.snowfall.js ├── study-io ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── demo │ ├── aio │ ├── AioClient.java │ └── AioServer.java │ ├── bio │ ├── BioClient.java │ └── BioServer.java │ └── nio │ ├── NioClient.java │ └── NioServer.java ├── study-net ├── README.MD ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── demo │ └── longconn │ ├── ClientTest.java │ ├── KeepAlive.java │ ├── ServerTest.java │ ├── client │ └── Client.java │ └── server │ ├── ClientState.java │ └── Server.java ├── study-other ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── jvm │ └── CpuTest.java ├── study-redis ├── README.MD ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── demo │ │ │ ├── RedisApplication.java │ │ │ ├── domain │ │ │ └── Message.java │ │ │ ├── p2p │ │ │ ├── Constant.java │ │ │ ├── Consumer.java │ │ │ └── Producer.java │ │ │ ├── pubsub │ │ │ ├── Constant.java │ │ │ ├── Consumer.java │ │ │ ├── Producer.java │ │ │ └── RedisMsgPubSubListener.java │ │ │ └── redis │ │ │ ├── RedisConfig.java │ │ │ ├── RedisPoolFactory.java │ │ │ └── RedisService.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ ├── RedisPubTest.java │ ├── RedisQueueTest.java │ └── RedisSubTest.java ├── study-transcation ├── README.md ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── demo │ │ │ ├── TranscationApplication.java │ │ │ ├── entity │ │ │ ├── Log.java │ │ │ └── User.java │ │ │ ├── mapper │ │ │ ├── LogMapper.java │ │ │ └── UserMapper.java │ │ │ ├── redis │ │ │ ├── RedisConfig.java │ │ │ ├── RedisPoolFactory.java │ │ │ └── RedisService.java │ │ │ ├── service │ │ │ ├── ILogService.java │ │ │ ├── IUserService.java │ │ │ └── impl │ │ │ │ ├── LogService.java │ │ │ │ └── UserService.java │ │ │ ├── txtest │ │ │ ├── ITxService.java │ │ │ ├── TxRedisService.java │ │ │ └── TxService.java │ │ │ └── util │ │ │ ├── JedisClient.java │ │ │ ├── JedisClientPool.java │ │ │ ├── LockEnum.java │ │ │ └── LockUtil.java │ └── resources │ │ ├── application.properties │ │ ├── application.yml │ │ ├── generatorConfig.xml │ │ └── mapper │ │ ├── LogMapper.xml │ │ └── UserMapper.xml │ └── test │ └── java │ └── com │ └── demo │ ├── RedisAndTxTest.java │ ├── RedisTest.java │ └── TxTest.java ├── study-uml ├── README.MD ├── pom.xml └── src │ └── uml │ ├── alipay1.puml │ ├── alipay2.puml │ ├── alipay3.puml │ ├── alipay4.puml │ ├── lxh1.puml │ ├── lxh2.puml │ ├── test1.puml │ ├── test2.puml │ └── test3.puml └── study-zk ├── pom.xml └── src └── main └── java └── com └── demo └── package-info.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea/ 3 | target/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 手写源码-demo代码 2 | -------------------------------------------------------------------------------- /code-ioc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.demo 13 | code-ioc 14 | jar 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-compiler-plugin 20 | 21 | 1.8 22 | 1.8 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /code-ioc/src/main/java/com/demo/IUserService.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | /** 4 | * @Author: cxx 5 | * @Date: 2019/10/1 22:40 6 | */ 7 | public interface IUserService { 8 | public void delete(String id); 9 | } 10 | -------------------------------------------------------------------------------- /code-ioc/src/main/java/com/demo/LogService.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import com.ioc.annotation.MyComponent; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/3 12:50 8 | */ 9 | @MyComponent 10 | public class LogService { 11 | public void print(String msg){ 12 | System.out.println("print log:" + msg); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /code-ioc/src/main/java/com/demo/MainTest.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import com.ioc.core.MyIoc; 4 | 5 | 6 | /** 7 | * @Author: cxx 8 | * @Date: 2019/10/3 11:34 9 | */ 10 | public class MainTest { 11 | public static void main(String[] args) { 12 | IUserService userService = (IUserService) MyIoc.getObject(UserService.class); 13 | userService.delete("100"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /code-ioc/src/main/java/com/demo/UserService.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import com.ioc.annotation.MyAutowired; 4 | import com.ioc.annotation.MyComponent; 5 | 6 | /** 7 | * @Author: cxx 8 | * @Date: 2019/10/1 22:40 9 | */ 10 | @MyComponent 11 | public class UserService implements IUserService { 12 | @MyAutowired 13 | private LogService logService; 14 | 15 | public void delete(String id) { 16 | System.out.println("删除用户 id:" + id); 17 | logService.print("删除用户"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /code-ioc/src/main/java/com/ioc/annotation/MyAutowired.java: -------------------------------------------------------------------------------- 1 | package com.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/3 11:39 8 | */ 9 | @Documented 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.FIELD) 12 | public @interface MyAutowired { 13 | } 14 | -------------------------------------------------------------------------------- /code-ioc/src/main/java/com/ioc/annotation/MyComponent.java: -------------------------------------------------------------------------------- 1 | package com.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/3 11:36 8 | */ 9 | @Documented 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.TYPE) 12 | public @interface MyComponent { 13 | } 14 | -------------------------------------------------------------------------------- /code-ioc/src/main/resources/ioc.properties: -------------------------------------------------------------------------------- 1 | scan.package=com.demo -------------------------------------------------------------------------------- /code-netty-tomcat/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-netty-tomcat/img/1.jpg -------------------------------------------------------------------------------- /code-netty-tomcat/img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-netty-tomcat/img/2.jpg -------------------------------------------------------------------------------- /code-netty-tomcat/img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-netty-tomcat/img/3.png -------------------------------------------------------------------------------- /code-netty-tomcat/img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-netty-tomcat/img/4.png -------------------------------------------------------------------------------- /code-netty-tomcat/img/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-netty-tomcat/img/5.jpg -------------------------------------------------------------------------------- /code-netty-tomcat/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.demo 13 | code-netty-tomcat 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 20 | 8 21 | 8 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | io.netty 30 | netty-all 31 | 4.1.31.Final 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /code-netty-tomcat/src/main/java/com/catalina/config/Config.java: -------------------------------------------------------------------------------- 1 | package com.catalina.config; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Properties; 6 | import java.util.Set; 7 | 8 | /** 9 | * User: lanxinghua 10 | * Date: 2019/10/9 10:50 11 | * Desc: 加载自定义配置 12 | */ 13 | public class Config { 14 | private static Map config; 15 | 16 | public static void load(String... props){ 17 | new Config(props); 18 | } 19 | 20 | public Config(String... props) { 21 | for (String path : props) { 22 | Properties p = new Properties(); 23 | try { 24 | p.load(Config.class.getClassLoader().getResourceAsStream(path)); 25 | config = new HashMap(); 26 | for (Object key : p.keySet()) { 27 | String keyStr = key.toString(); 28 | config.put(keyStr, p.getProperty(keyStr)); 29 | } 30 | }catch (Exception e){ 31 | e.printStackTrace(); 32 | } 33 | } 34 | } 35 | 36 | /** 37 | * 获取已加载的配置信息 38 | * @param key 39 | * @return 40 | */ 41 | public static String getValue(String key) { 42 | return config.get(key); 43 | } 44 | 45 | /** 46 | * 获取所有的key值 47 | * @return 48 | */ 49 | public static Set getKeys(){ 50 | return config.keySet(); 51 | } 52 | 53 | public static void main(String[] args) { 54 | Config.load("web.properties"); 55 | System.out.println(Config.getKeys().toString()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /code-netty-tomcat/src/main/java/com/catalina/http/Request.java: -------------------------------------------------------------------------------- 1 | package com.catalina.http; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.handler.codec.http.HttpRequest; 5 | import io.netty.handler.codec.http.QueryStringDecoder; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | /** 11 | * User: lanxinghua 12 | * Date: 2019/10/9 09:27 13 | * Desc: 14 | */ 15 | public class Request { 16 | private ChannelHandlerContext ctx; 17 | private HttpRequest request; 18 | 19 | public Request(ChannelHandlerContext ctx, HttpRequest request) { 20 | this.ctx = ctx; 21 | this.request = request; 22 | } 23 | 24 | public String getUri(){ 25 | return request.uri(); 26 | } 27 | 28 | public String getRequestType(){ 29 | return request.method().name(); 30 | } 31 | 32 | public Map> getParamters(){ 33 | QueryStringDecoder queryStringDecoder = new QueryStringDecoder(getUri()); 34 | return queryStringDecoder.parameters(); 35 | } 36 | 37 | public String getParamter(String key){ 38 | Map> map = getParamters(); 39 | List params = map.get(key); 40 | if (params == null || params.isEmpty()){ 41 | return null; 42 | } 43 | return params.get(0); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /code-netty-tomcat/src/main/java/com/catalina/http/Response.java: -------------------------------------------------------------------------------- 1 | package com.catalina.http; 2 | 3 | import io.netty.buffer.Unpooled; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.http.*; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | /** 11 | * User: lanxinghua 12 | * Date: 2019/10/9 09:27 13 | * Desc: 14 | */ 15 | public class Response { 16 | private ChannelHandlerContext ctx; 17 | private HttpRequest req; 18 | private static Map statusMapping = new HashMap(); 19 | private String charSet = "utf-8"; 20 | private String contentType = "text/json"; 21 | 22 | public void setCharSet(String charSet) { 23 | this.charSet = charSet; 24 | } 25 | 26 | public void setContentType(String contentType) { 27 | this.contentType = contentType; 28 | } 29 | 30 | static{ 31 | statusMapping.put(200, HttpResponseStatus.OK); 32 | statusMapping.put(404, HttpResponseStatus.NOT_FOUND); 33 | } 34 | 35 | public Response(ChannelHandlerContext ctx, HttpRequest req) { 36 | this.ctx = ctx; 37 | this.req = req; 38 | } 39 | 40 | public void write(String text){ 41 | write(text, 200); 42 | } 43 | 44 | public void write(String text, Integer status){ 45 | try { 46 | if (text.isEmpty()){ 47 | return; 48 | } 49 | FullHttpResponse response = new DefaultFullHttpResponse( 50 | HttpVersion.HTTP_1_1, 51 | statusMapping.get(status), 52 | Unpooled.wrappedBuffer(text.getBytes(charSet)) 53 | ); 54 | response.headers().set("Content-Type", contentType); 55 | response.headers().set("Content-Length", response.content().readableBytes()); 56 | response.headers().set("expires", 0); 57 | response.headers().set("server", "my netty tomcat"); 58 | ctx.write(response); 59 | }catch (Exception e){ 60 | e.printStackTrace(); 61 | }finally { 62 | ctx.flush(); 63 | ctx.close(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /code-netty-tomcat/src/main/java/com/catalina/http/Servlet.java: -------------------------------------------------------------------------------- 1 | package com.catalina.http; 2 | 3 | /** 4 | * User: lanxinghua 5 | * Date: 2019/10/9 09:27 6 | * Desc: 自定义servlet 7 | */ 8 | public abstract class Servlet { 9 | 10 | public abstract void doGet(Request req, Response resp) throws Exception; 11 | 12 | public abstract void doPost(Request req, Response resp) throws Exception; 13 | } 14 | -------------------------------------------------------------------------------- /code-netty-tomcat/src/main/java/com/catalina/server/BootStrap.java: -------------------------------------------------------------------------------- 1 | package com.catalina.server; 2 | 3 | /** 4 | * User: lanxinghua 5 | * Date: 2019/10/9 09:31 6 | * Desc: 服务启动 7 | */ 8 | public class BootStrap { 9 | public static void main(String[] args) { 10 | new Tomcat().start(8080); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-netty-tomcat/src/main/java/com/catalina/servlet/TestServlet.java: -------------------------------------------------------------------------------- 1 | package com.catalina.servlet; 2 | 3 | import com.catalina.http.Request; 4 | import com.catalina.http.Response; 5 | import com.catalina.http.Servlet; 6 | 7 | /** 8 | * User: lanxinghua 9 | * Date: 2019/10/9 09:29 10 | * Desc: 11 | */ 12 | public class TestServlet extends Servlet { 13 | public void doGet(Request req, Response resp) throws Exception { 14 | this.doPost(req, resp); 15 | } 16 | 17 | public void doPost(Request req, Response resp) throws Exception { 18 | String name = req.getParamter("name"); 19 | resp.setCharSet("UTF-8"); 20 | resp.setContentType("text/html; charset=utf-8"); 21 | String html = "

自己手写Netty实现Tomcat&热部署


"; 22 | html += "
name:"+ name +"
"; 23 | html += "update....."; 24 | resp.write(html); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /code-netty-tomcat/src/main/java/com/hot/MyClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.hot; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | /** 7 | * User: lanxinghua 8 | * Date: 2019/10/9 11:52 9 | * Desc: 实现热部署核心,通过自定义类加载器,创建新的对象,jvm进行加载 10 | */ 11 | public class MyClassLoader extends ClassLoader { 12 | @Override 13 | public Class findClass(String name) throws ClassNotFoundException { 14 | try { 15 | // 文件名称 16 | String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class"; 17 | // 读取文件流 18 | InputStream is = this.getClass().getResourceAsStream("/com/catalina/servlet/" + fileName); 19 | // 读取字节 20 | byte[] b = new byte[is.available()]; 21 | is.read(b); 22 | //数据给JVM识别Class对象 23 | return defineClass(name,b, 0, b.length); 24 | } catch (IOException e) { 25 | throw new ClassNotFoundException(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /code-netty-tomcat/src/main/resources/web.properties: -------------------------------------------------------------------------------- 1 | application.name=web 2 | 3 | servlet.test=testServlet 4 | servlet.test.className=com.catalina.servlet.TestServlet 5 | servlet.test.urlPattern=/test* 6 | -------------------------------------------------------------------------------- /code-netty/README.md: -------------------------------------------------------------------------------- 1 | ## 手写简化版netty 2 | netty 源码比较复杂,考虑了许多可扩展、安全、性能等,netty 的核心就隐藏在这百花深处。我们就考虑核心的东西,实现简单版的netty, 3 | 更好理解netty核心原理。 4 | 5 | ## netty原理 6 | 7 | ![avatar](https://raw.githubusercontent.com/chenxingxing6/sourcecode/master/code-netty/img/1.jpg) 8 | 9 | 10 | ##### Reactor线程模型 11 | ![avatar](https://raw.githubusercontent.com/chenxingxing6/sourcecode/master/code-netty/img/2.jpg) 12 | 13 | 请求过程: 14 | > 1.客户端请求,reactor线程进行处理accept,专门负责轮询 15 | > 2.分发请求给对应的worker线程 16 | > 3.worker线程更加配置,继续分发或者处理请求 17 | 18 | MainReactorThread 与 SubReactorThread 线程,分别用于处理 ACCEPT 事件与其它 I/O 事件。 19 | MainReactorThread: 20 | 21 | > 在 main 方法中被调用 start 方法; 22 | 只注册了 ServerSocketChanel 的 ACCETP 事件; 23 | 知道全部 SubReactorThread 对象; 24 | 具有一个从 SubReactorThread 组中挑选出某一个 Thread 的方法; 25 | 具有启动 SubReactorThread 的方法; 26 | 将 channnel 视为 ServerSocketChannel; 27 | 调用 ServerSocketChannel.accept() 方法取得一个客户端的 SocketChannel; 28 | 把 SocketCahnnel 注册到 I/O 线程,关注 READ 事件。 29 | 30 | SubReactorThread: 31 | 32 | > 在 MainReactorThread 方法中被调用 start 方法; 33 | 只注册了 SocketChannel 的 READ 事件; 34 | 知道更多的 workThread,用于业务操作; 35 | 具有挑选 workThread 的方法; 36 | 从 channel 中读取数据; 37 | 把业务操作提交到 workThread; 38 | 写入响应数据; 39 | 40 | 41 | -------------------------------------------------------------------------------- /code-netty/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-netty/img/1.jpg -------------------------------------------------------------------------------- /code-netty/img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-netty/img/2.jpg -------------------------------------------------------------------------------- /code-netty/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | code-netty 13 | 14 | 15 | 16 | io.netty 17 | netty-all 18 | 4.1.31.Final 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /code-netty/src/main/java/com/demo/ClientStart.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import com.demo.bootstrap.ServerBootstrap; 4 | import com.demo.channel.NioSelectorRunnablePool; 5 | 6 | import java.net.InetSocketAddress; 7 | import java.util.concurrent.Executors; 8 | 9 | /** 10 | * User: lanxinghua 11 | * Date: 2019/10/17 09:48 12 | * Desc: 13 | */ 14 | public class ClientStart { 15 | public static void main(String[] args) { 16 | // 初始化线程 17 | NioSelectorRunnablePool pool = new NioSelectorRunnablePool(Executors.newCachedThreadPool()); 18 | // 配置 19 | ServerBootstrap bootstrap = new ServerBootstrap(pool); 20 | // 绑定端口 21 | bootstrap.connect("localhost", 8888); 22 | System.out.println("client start......"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /code-netty/src/main/java/com/demo/ServerStart.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import com.demo.bootstrap.ServerBootstrap; 4 | import com.demo.channel.NioSelectorRunnablePool; 5 | 6 | import java.net.InetSocketAddress; 7 | import java.util.concurrent.Executors; 8 | 9 | /** 10 | * User: lanxinghua 11 | * Date: 2019/10/17 09:48 12 | * Desc: 13 | */ 14 | public class ServerStart { 15 | public static void main(String[] args) { 16 | // 初始化线程 17 | NioSelectorRunnablePool pool = new NioSelectorRunnablePool(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); 18 | // 配置 19 | ServerBootstrap bootstrap = new ServerBootstrap(pool); 20 | // 绑定端口 21 | bootstrap.bind(new InetSocketAddress(8888)); 22 | System.out.println("server start......"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /code-netty/src/main/java/com/demo/channel/IBoss.java: -------------------------------------------------------------------------------- 1 | package com.demo.channel; 2 | 3 | import java.nio.channels.ServerSocketChannel; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/10/15 09:34 8 | * Desc: 9 | */ 10 | public interface IBoss { 11 | /** 12 | * 加入一个新的serversockets 13 | * @param serverSocketChannel 14 | */ 15 | public void registerAcceptChannelTask(ServerSocketChannel serverSocketChannel); 16 | } 17 | -------------------------------------------------------------------------------- /code-netty/src/main/java/com/demo/channel/IWorker.java: -------------------------------------------------------------------------------- 1 | package com.demo.channel; 2 | 3 | import java.nio.channels.SocketChannel; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/10/15 09:36 8 | * Desc: 9 | */ 10 | public interface IWorker { 11 | /** 12 | * 加入新的客户端会话 13 | * @param socketChannel 14 | */ 15 | public void registerNewChannelTask(SocketChannel socketChannel); 16 | } 17 | -------------------------------------------------------------------------------- /code-netty/src/main/java/com/demo/channel/NioSelectorRunnablePool.java: -------------------------------------------------------------------------------- 1 | package com.demo.channel; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.concurrent.Executor; 7 | import java.util.concurrent.atomic.AtomicInteger; 8 | 9 | /** 10 | * User: lanxinghua 11 | * Date: 2019/10/15 09:41 12 | * Desc: selector线程管理者 13 | */ 14 | public class NioSelectorRunnablePool { 15 | // boss线程组 16 | private final AtomicInteger bossIndex = new AtomicInteger(); 17 | private List bosses = new ArrayList(); 18 | 19 | // worker线程组 20 | private final AtomicInteger workerIndex = new AtomicInteger(); 21 | private List workers = new ArrayList(); 22 | 23 | public NioSelectorRunnablePool(Executor worker) { 24 | initWorker(worker, Runtime.getRuntime().availableProcessors() * 2); 25 | } 26 | 27 | // 初始化 28 | public NioSelectorRunnablePool(Executor boss, Executor worker){ 29 | initBoss(boss, 1); 30 | initWorker(worker, Runtime.getRuntime().availableProcessors() * 2); 31 | } 32 | 33 | private void initBoss(Executor boss, int count){ 34 | for (int i = 0; i < count; i++) { 35 | bosses.add(new NioServerBoss(boss, "boss thread" + (i + 1), this)); 36 | } 37 | } 38 | 39 | private void initWorker(Executor worker, int count){ 40 | for (int i = 0; i < count; i++) { 41 | workers.add(new NioServerWorker(worker, "worker thread" + (i + 1), this)); 42 | } 43 | } 44 | 45 | public IWorker nextWorker(){ 46 | return workers.get(Math.abs(workerIndex.getAndIncrement() % workers.size())); 47 | } 48 | 49 | public IBoss nextBoss(){ 50 | return bosses.get(Math.abs(bossIndex.getAndIncrement() % bosses.size())); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /code-netty/src/main/java/com/demo/channel/NioServerBoss.java: -------------------------------------------------------------------------------- 1 | package com.demo.channel; 2 | 3 | import java.nio.channels.SelectionKey; 4 | import java.nio.channels.Selector; 5 | import java.nio.channels.ServerSocketChannel; 6 | import java.nio.channels.SocketChannel; 7 | import java.util.Iterator; 8 | import java.util.Set; 9 | import java.util.concurrent.Executor; 10 | 11 | /** 12 | * User: lanxinghua 13 | * Date: 2019/10/17 09:38 14 | * Desc: 15 | */ 16 | public class NioServerBoss extends AbstractNioSelector implements IBoss { 17 | 18 | public NioServerBoss(Executor executor, String threadName, NioSelectorRunnablePool selectorRunnablePool) { 19 | super(executor, threadName, selectorRunnablePool); 20 | } 21 | 22 | protected int select(Selector selector) throws Exception{ 23 | return selector.select(); 24 | } 25 | 26 | // selector业务处理 27 | protected void process(Selector selector) throws Exception{ 28 | Set selectionKeys = selector.selectedKeys(); 29 | if (selectionKeys.isEmpty()){ 30 | return; 31 | } 32 | Iterator iterator = selectionKeys.iterator(); 33 | while (iterator.hasNext()){ 34 | SelectionKey key = iterator.next(); 35 | iterator.remove(); 36 | ServerSocketChannel server = (ServerSocketChannel) key.channel(); 37 | // 新客户端 38 | SocketChannel channel = server.accept(); 39 | // 设为非阻塞 40 | channel.configureBlocking(false); 41 | // 获取worker线程 42 | IWorker worker = selectorRunnablePool.nextWorker(); 43 | // 注册新客户端接入任务 44 | worker.registerNewChannelTask(channel); 45 | System.out.println("新客户端连接......"); 46 | } 47 | } 48 | 49 | public void registerAcceptChannelTask(final ServerSocketChannel serverSocketChannel) { 50 | final Selector selector = this.selector; 51 | addTask(new Runnable() { 52 | public void run() { 53 | try { 54 | serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); 55 | }catch (Exception e){ 56 | e.printStackTrace(); 57 | } 58 | } 59 | }); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /code-netty/src/main/resources/config.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-netty/src/main/resources/config.properties -------------------------------------------------------------------------------- /code-proxy/img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-proxy/img/1.png -------------------------------------------------------------------------------- /code-proxy/img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-proxy/img/2.jpg -------------------------------------------------------------------------------- /code-proxy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.demo 13 | code-proxy 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 20 | 1.6 21 | 1.6 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | cglib 30 | cglib 31 | 3.2.5 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /code-proxy/src/main/java/com/IUserService.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | /** 4 | * @Author: cxx 5 | * @Date: 2019/10/1 22:40 6 | */ 7 | public interface IUserService { 8 | public void delete(String id); 9 | } 10 | -------------------------------------------------------------------------------- /code-proxy/src/main/java/com/UserService.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | /** 4 | * @Author: cxx 5 | * @Date: 2019/10/1 22:40 6 | */ 7 | public class UserService implements IUserService { 8 | public void delete(String id) { 9 | System.out.println("删除用户 id:" + id); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /code-proxy/src/main/java/com/cglib/CglibTest.java: -------------------------------------------------------------------------------- 1 | package com.cglib; 2 | 3 | import com.UserService; 4 | import net.sf.cglib.core.DebuggingClassWriter; 5 | import net.sf.cglib.proxy.Enhancer; 6 | import net.sf.cglib.proxy.MethodInterceptor; 7 | import net.sf.cglib.proxy.MethodProxy; 8 | 9 | import java.lang.reflect.Method; 10 | 11 | /** 12 | * @Author: cxx 13 | * @Date: 2019/10/1 22:49 14 | */ 15 | public class CglibTest { 16 | public static void main(String[] args) { 17 | //代理类class文件存入本地磁盘 18 | System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "F:\\code"); 19 | Enhancer enhancer = new Enhancer(); 20 | enhancer.setSuperclass(UserService.class); 21 | enhancer.setCallback(new MethodInterceptor() { 22 | public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 23 | System.out.println("before"); 24 | methodProxy.invokeSuper(o, objects); 25 | System.out.println("after"); 26 | return null; 27 | } 28 | }); 29 | UserService userServiceProxy = (UserService) enhancer.create(); 30 | userServiceProxy.delete("100"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /code-proxy/src/main/java/com/jdk/JdkTest.java: -------------------------------------------------------------------------------- 1 | package com.jdk; 2 | 3 | import com.IUserService; 4 | import com.UserService; 5 | 6 | import java.lang.reflect.InvocationHandler; 7 | import java.lang.reflect.Method; 8 | import java.lang.reflect.Proxy; 9 | 10 | /** 11 | * @Author: cxx 12 | * @Date: 2019/10/1 22:41 13 | */ 14 | public class JdkTest { 15 | public static void main(String[] args) { 16 | IUserService userServiceProxy = (IUserService) Proxy.newProxyInstance( 17 | UserService.class.getClassLoader(), 18 | UserService.class.getInterfaces(), 19 | new InvocationHandler() { 20 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 21 | System.out.println("before"); 22 | method.invoke(new UserService(), args); 23 | System.out.println("after"); 24 | return null; 25 | } 26 | } 27 | ); 28 | userServiceProxy.delete("100"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /code-proxy/src/main/java/com/my/$ProxyMy.java: -------------------------------------------------------------------------------- 1 | package com.my; 2 | 3 | import com.IUserService; 4 | 5 | import java.lang.reflect.Method; 6 | 7 | /** 8 | * @Author: cxx 9 | * @Date: 2019/10/2 11:29 10 | * 动态生成代理类:如下 11 | */ 12 | public class $ProxyMy implements IUserService { 13 | private MyInvocationHandler invocationHandler; 14 | 15 | public $ProxyMy(MyInvocationHandler invocationHandler) { 16 | this.invocationHandler = invocationHandler; 17 | } 18 | 19 | public void delete(String id) { 20 | try { 21 | Method m = IUserService.class.getMethod("delete", String.class); 22 | invocationHandler.invoke(this, m, new Object[]{id}); 23 | } catch (Throwable throwable) { 24 | throwable.printStackTrace(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /code-proxy/src/main/java/com/my/MyClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.my; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | 7 | /** 8 | * @Author: cxx 9 | * @Date: 2019/10/2 14:24 10 | */ 11 | public class MyClassLoader extends ClassLoader{ 12 | private String baseDir; 13 | 14 | public MyClassLoader() { 15 | this.baseDir = this.getClass().getResource("").getFile(); 16 | } 17 | 18 | @Override 19 | protected Class findClass(String name) throws ClassNotFoundException { 20 | String className = this.getClass().getPackage().getName() + "." + name; 21 | if (baseDir != null && baseDir != ""){ 22 | File f = new File(baseDir + "/" + name +".class"); 23 | ByteArrayOutputStream out = null; 24 | FileInputStream fis = null; 25 | if (f.exists()){ 26 | try { 27 | fis = new FileInputStream(f); 28 | out = new ByteArrayOutputStream(); 29 | byte[] b = new byte[1024]; 30 | int len; 31 | while ((len = fis.read(b)) != -1){ 32 | out.write(b, 0, len); 33 | } 34 | return defineClass(className, out.toByteArray(), 0, out.size()); 35 | }catch (Exception e){ 36 | e.printStackTrace(); 37 | }finally { 38 | if (fis != null){ 39 | try { 40 | fis.close(); 41 | }catch (Exception e){ 42 | e.printStackTrace(); 43 | } 44 | } 45 | if (out != null){ 46 | try { 47 | out.close(); 48 | }catch (Exception e){ 49 | e.printStackTrace(); 50 | } 51 | } 52 | // 查看.class文件 53 | // f.delete(); 54 | } 55 | } 56 | } 57 | return null; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /code-proxy/src/main/java/com/my/MyInvocationHandler.java: -------------------------------------------------------------------------------- 1 | package com.my; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/2 11:11 8 | */ 9 | public interface MyInvocationHandler { 10 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; 11 | } 12 | -------------------------------------------------------------------------------- /code-proxy/src/main/java/com/my/MyTest.java: -------------------------------------------------------------------------------- 1 | package com.my; 2 | 3 | import com.IUserService; 4 | import com.UserService; 5 | 6 | import java.lang.reflect.Method; 7 | 8 | /** 9 | * @Author: cxx 10 | * @Date: 2019/10/2 11:13 11 | */ 12 | public class MyTest { 13 | public static void main(String[] args) { 14 | IUserService userServiceProxy = (IUserService) MyProxy.newProxyInstance( 15 | new MyClassLoader(), 16 | UserService.class.getInterfaces(), 17 | new MyInvocationHandler() { 18 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 19 | System.out.println("before"); 20 | method.invoke(new UserService(), args); 21 | System.out.println("after"); 22 | return null; 23 | } 24 | } 25 | ); 26 | userServiceProxy.delete("100"); 27 | 28 | // 其实就是生成一个代理类 29 | IUserService proxyMy = new $ProxyMy(new MyInvocationHandler() { 30 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 31 | System.out.println("before"); 32 | method.invoke(new UserService(), args); 33 | System.out.println("after"); 34 | return null; 35 | } 36 | }); 37 | //proxyMy.delete("100"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /code-redis/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/1.jpg -------------------------------------------------------------------------------- /code-redis/img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/2.png -------------------------------------------------------------------------------- /code-redis/img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/3.png -------------------------------------------------------------------------------- /code-redis/img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/4.png -------------------------------------------------------------------------------- /code-redis/img/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/5.png -------------------------------------------------------------------------------- /code-redis/img/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/6.png -------------------------------------------------------------------------------- /code-redis/img/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/7.png -------------------------------------------------------------------------------- /code-redis/img/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/8.png -------------------------------------------------------------------------------- /code-redis/img/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/9.png -------------------------------------------------------------------------------- /code-redis/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.demo 13 | code-redis 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | redis.clients 30 | jedis 31 | 2.9.0 32 | 33 | 34 | junit 35 | junit 36 | 4.12 37 | test 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/JedisTest.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import redis.clients.jedis.Jedis; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * @Author: cxx 9 | * @Date: 2019/11/3 23:28 10 | */ 11 | public class JedisTest { 12 | public static void main(String[] args) throws Exception{ 13 | Jedis jedis=new Jedis("localhost", 6379); 14 | String result = jedis.ping(); 15 | System.out.println(result); 16 | 17 | TimeUnit.SECONDS.sleep(2); 18 | //关闭jedis 19 | jedis.close(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/MyRedisService.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import com.demo.command.ICommand; 4 | import com.demo.data.PermanentData; 5 | import com.demo.procotol.MyDecode; 6 | 7 | import java.io.InputStream; 8 | import java.io.OutputStream; 9 | import java.net.ServerSocket; 10 | import java.net.Socket; 11 | import java.util.concurrent.ExecutorService; 12 | import java.util.concurrent.Executors; 13 | import java.util.concurrent.TimeUnit; 14 | 15 | /** 16 | * @Author: cxx 17 | * @Date: 2019/11/3 19:48 18 | */ 19 | public class MyRedisService { 20 | 21 | public static void main(String[] args) { 22 | new MyRedisService().start(6379); 23 | } 24 | 25 | public void start(int port){ 26 | // 1.加载持久化数据 27 | loadData(); 28 | ExecutorService executor = Executors.newFixedThreadPool(20000); 29 | ServerSocket serverSocket = null; 30 | try { 31 | // 循环接受客户端连接 32 | serverSocket = new ServerSocket(port); 33 | System.out.println("等待客户端连接...."); 34 | while (true){ 35 | final Socket socket = serverSocket.accept(); 36 | executor.execute(() -> { 37 | try { 38 | // 持续提供业务服务 39 | while (true){ 40 | InputStream is = socket.getInputStream(); 41 | OutputStream os = socket.getOutputStream(); 42 | // 解析命令 43 | ICommand command = new MyDecode(is, os).getCommand(); 44 | if (command != null){ 45 | command.run(os); 46 | } 47 | TimeUnit.MILLISECONDS.sleep(10); 48 | } 49 | }catch (Exception e){ 50 | try { 51 | socket.close(); 52 | }catch (Exception e1){ 53 | } 54 | } 55 | }); 56 | } 57 | }catch (Exception e){ 58 | try { 59 | serverSocket.close(); 60 | }catch (Exception e1){ 61 | 62 | } 63 | } 64 | } 65 | 66 | public void loadData(){ 67 | PermanentData.getInstance().readFromListProfile(); 68 | PermanentData.getInstance().readFromMapProfile(); 69 | System.out.println("数据加载完成...."); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/EXITCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import java.io.OutputStream; 4 | import java.util.List; 5 | 6 | /** 7 | * @Author: cxx 8 | * @Date: 2019/11/3 19:51 9 | */ 10 | public class EXITCommand implements ICommand { 11 | public List args; 12 | 13 | public void run(OutputStream out) { 14 | if (args.size() == 1 && ("exit".equals(args.get(0)))){ 15 | System.exit(0); 16 | } 17 | } 18 | 19 | public void setArgs(List args) { 20 | this.args = args; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/GETCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.data.PermanentData; 5 | import com.demo.procotol.Protocolcode; 6 | 7 | import java.io.OutputStream; 8 | import java.util.List; 9 | 10 | /** 11 | * @Author: cxx 12 | * @Date: 2019/11/3 22:30 13 | */ 14 | public class GETCommand implements ICommand { 15 | DbData dbData = DbData.getDatabase(); 16 | List args; 17 | 18 | @Override 19 | public void run(OutputStream out) { 20 | if (args.size() == 1){ 21 | String key = new String((byte[]) args.remove(0)); 22 | try { 23 | String value = dbData.str.remove(key); 24 | Protocolcode.writeBulkString(out,value); 25 | // TODO: 2019/11/3 持久化到文件里 26 | }catch (Exception e){ 27 | e.printStackTrace(); 28 | } 29 | }else { 30 | try { 31 | Protocolcode.writeError(out, "Wrong Format"); 32 | }catch (Exception e){ 33 | e.printStackTrace(); 34 | } 35 | } 36 | } 37 | 38 | @Override 39 | public void setArgs(List args) { 40 | this.args = args; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/HGETCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.procotol.Protocolcode; 5 | 6 | import java.io.OutputStream; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | 10 | /** 11 | * @Author: cxx 12 | * @Date: 2019/11/3 19:53 13 | */ 14 | public class HGETCommand implements ICommand{ 15 | DbData dbData = DbData.getDatabase(); 16 | List args; 17 | 18 | @Override 19 | public void run(OutputStream out) { 20 | if (args.size() == 2){ 21 | String key = new String((byte[]) args.remove(0)); 22 | String field = new String((byte[]) args.remove(0)); 23 | HashMap map = dbData.getDatabase().getHash(key); 24 | String value = map.get(field); 25 | try { 26 | Protocolcode.writeBulkString(out, value); 27 | } catch (Exception e) { 28 | e.printStackTrace(); 29 | } 30 | }else { 31 | try { 32 | Protocolcode.writeError(out, "Wrong Format"); 33 | } catch (Exception e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | } 38 | 39 | @Override 40 | public void setArgs(List args) { 41 | this.args = args; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/HSETCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.data.PermanentData; 5 | import com.demo.procotol.Protocolcode; 6 | 7 | import java.io.OutputStream; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | /** 13 | * @Author: cxx 14 | * @Date: 2019/11/3 19:53 15 | */ 16 | public class HSETCommand implements ICommand { 17 | DbData dbData = DbData.getDatabase(); 18 | List args; 19 | 20 | @Override 21 | public void run(OutputStream out) { 22 | if (args.size() == 3){ 23 | String key = new String((byte[]) args.remove(0)); 24 | String field = new String((byte[]) args.remove(0)); 25 | String value = new String((byte[]) args.remove(0)); 26 | HashMap map = dbData.getDatabase().getHash(key); 27 | try { 28 | if (map.containsKey(field)) { 29 | Protocolcode.writeInteger(out, 0); 30 | } else { 31 | Protocolcode.writeInteger(out, 1); 32 | } 33 | map.put(field, value); 34 | PermanentData.getInstance().writetoMapProfile(); 35 | } catch (Exception ex) { 36 | ex.printStackTrace(); 37 | } 38 | }else { 39 | try { 40 | Protocolcode.writeError(out, "Wrong Format"); 41 | } catch (Exception e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | } 46 | 47 | @Override 48 | public void setArgs(List args) { 49 | this.args = args; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/ICommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import java.io.OutputStream; 4 | import java.util.List; 5 | 6 | /** 7 | * @Author: cxx 8 | * @Date: 2019/11/3 19:49 9 | */ 10 | public interface ICommand { 11 | public void run(OutputStream out); 12 | 13 | public void setArgs(List args); 14 | } 15 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/INFOCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.procotol.Protocolcode; 5 | 6 | import java.io.OutputStream; 7 | import java.util.List; 8 | 9 | /** 10 | * @Author: cxx 11 | * @Date: 2019/11/3 23:06 12 | */ 13 | public class INFOCommand implements ICommand { 14 | private List args; 15 | private DbData dbData = DbData.getDatabase(); 16 | 17 | @Override 18 | public void run(OutputStream out) { 19 | try { 20 | out.write('+'); 21 | out.write("# Server".getBytes()); 22 | out.write("\r\n".getBytes()); 23 | out.flush(); 24 | } catch (Exception e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | 29 | @Override 30 | public void setArgs(List args) { 31 | this.args = args; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/LPOPCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.data.PermanentData; 5 | import com.demo.procotol.Protocolcode; 6 | 7 | import java.io.OutputStream; 8 | import java.util.List; 9 | 10 | /** 11 | * @Author: cxx 12 | * @Date: 2019/11/3 19:51 13 | */ 14 | public class LPOPCommand implements ICommand{ 15 | DbData dbData = DbData.getDatabase(); 16 | List args; 17 | 18 | @Override 19 | public void run(OutputStream out) { 20 | if (args.size() == 1) { 21 | String key = new String((byte[]) args.get(0)); 22 | try { 23 | if (dbData.getList(key).isEmpty()){ 24 | Protocolcode.writeBulkString(out,""); 25 | return; 26 | } 27 | String value=dbData.getList(key).remove(0); 28 | Protocolcode.writeBulkString(out,value); 29 | PermanentData.getInstance().clearListProfile(); 30 | PermanentData.getInstance().writetoListProfile(); 31 | } catch (Exception e) { 32 | e.printStackTrace(); 33 | } 34 | } else { 35 | try { 36 | Protocolcode.writeError(out, "Wrong Format"); 37 | } catch (Exception e) { 38 | e.printStackTrace(); 39 | } 40 | } 41 | } 42 | 43 | @Override 44 | public void setArgs(List args) { 45 | this.args = args; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/LPUSHCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.data.PermanentData; 5 | import com.demo.procotol.Protocolcode; 6 | 7 | import java.io.OutputStream; 8 | import java.util.List; 9 | 10 | /** 11 | * @Author: cxx 12 | * @Date: 2019/11/3 19:51 13 | */ 14 | public class LPUSHCommand implements ICommand { 15 | DbData dbData = DbData.getDatabase(); 16 | List args; 17 | 18 | @Override 19 | public void run(OutputStream out) { 20 | //接收到的是列表,列表拆解 21 | if (args.size() == 2) { 22 | String key = new String((byte[]) args.get(0)); 23 | String value = new String((byte[]) args.get(1)); 24 | List dateList = dbData.getList(key); 25 | dateList.add(0, value); 26 | try { 27 | Protocolcode.writeInteger(out, dateList.size()); 28 | PermanentData.getInstance().writetoListProfile(); 29 | } catch (Exception e) { 30 | e.printStackTrace(); 31 | } 32 | } else { 33 | try { 34 | Protocolcode.writeError(out, "Wrong Format"); 35 | } catch (Exception e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | } 40 | 41 | @Override 42 | public void setArgs(List args) { 43 | this.args = args; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/LRANGECommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.procotol.Protocolcode; 5 | 6 | import java.io.OutputStream; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * @Author: cxx 12 | * @Date: 2019/11/3 19:52 13 | */ 14 | public class LRANGECommand implements ICommand{ 15 | DbData dbData = DbData.getDatabase(); 16 | List args; 17 | 18 | @Override 19 | public void run(OutputStream out) { 20 | if (args.size() == 3) { 21 | String key = new String((byte[]) args.remove(0)); 22 | List dataBase = dbData.getDatabase().getList(key); 23 | int start = Integer.parseInt(new String((byte[]) args.remove(0))); 24 | int end = Integer.parseInt(new String((byte[]) args.remove(0))); 25 | List list=new ArrayList<>(); 26 | try { 27 | if (start >= 0 && start < dataBase.size()) { 28 | if (end < 0) { 29 | end = dataBase.size() + end; 30 | for(int i=end;i= dataBase.size()) { 36 | Protocolcode.writeArray(out, dataBase); 37 | } else { 38 | for(int i=start;i args) { 64 | this.args = args; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/PINGCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.procotol.Protocolcode; 5 | 6 | import java.io.OutputStream; 7 | import java.util.List; 8 | 9 | /** 10 | * @Author: cxx 11 | * @Date: 2019/11/3 23:06 12 | */ 13 | public class PINGCommand implements ICommand { 14 | private List args; 15 | private DbData dbData = DbData.getDatabase(); 16 | 17 | @Override 18 | public void run(OutputStream out) { 19 | try { 20 | Protocolcode.writeString(out, "PONG"); 21 | } catch (Exception e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | 26 | @Override 27 | public void setArgs(List args) { 28 | this.args = args; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/SADDCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.procotol.Protocolcode; 5 | 6 | import java.io.OutputStream; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | /** 11 | * @Author: cxx 12 | * @Date: 2019/11/3 19:53 13 | */ 14 | public class SADDCommand implements ICommand { 15 | DbData dbData = DbData.getDatabase(); 16 | List args; 17 | 18 | @Override 19 | public void run(OutputStream out) { 20 | if (args.size() == 2){ 21 | String key = new String((byte[]) args.remove(0)); 22 | String value = new String((byte[]) args.remove(0)); 23 | Set set = dbData.getSet(key); 24 | try { 25 | if (set.contains(value)) { 26 | //0代表将原有的数据更新 27 | Protocolcode.writeInteger(out, 0); 28 | } else { 29 | //1代表插入一条语句 30 | set.add(value); 31 | Protocolcode.writeInteger(out, 1); 32 | } 33 | } catch (Exception ex) { 34 | ex.printStackTrace(); 35 | } 36 | }else { 37 | try { 38 | Protocolcode.writeError(out, "Wrong Format"); 39 | } catch (Exception e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | } 44 | 45 | @Override 46 | public void setArgs(List args) { 47 | this.args = args; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/SCARDCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.procotol.Protocolcode; 5 | 6 | import java.io.OutputStream; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.Set; 10 | 11 | /** 12 | * @Author: cxx 13 | * @Date: 2019/11/3 22:41 14 | */ 15 | public class SCARDCommand implements ICommand{ 16 | DbData dbData = DbData.getDatabase(); 17 | List args; 18 | 19 | @Override 20 | public void run(OutputStream out) { 21 | if (args.size() == 1){ 22 | String key = new String((byte[]) args.remove(0)); 23 | Set set = dbData.getSet(key); 24 | try { 25 | if (set.isEmpty()) { 26 | Protocolcode.writeArray(out, new ArrayList<>()); 27 | } else { 28 | Protocolcode.writeArray(out, new ArrayList<>(set)); 29 | } 30 | } catch (Exception ex) { 31 | ex.printStackTrace(); 32 | } 33 | }else { 34 | try { 35 | Protocolcode.writeError(out, "Wrong Format"); 36 | } catch (Exception e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | } 41 | 42 | @Override 43 | public void setArgs(List args) { 44 | this.args = args; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/SELECTCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.procotol.Protocolcode; 5 | 6 | import java.io.OutputStream; 7 | import java.util.List; 8 | 9 | /** 10 | * @Author: cxx 11 | * @Date: 2019/11/3 23:06 12 | */ 13 | public class SELECTCommand implements ICommand { 14 | private List args; 15 | private DbData dbData = DbData.getDatabase(); 16 | 17 | @Override 18 | public void run(OutputStream out) { 19 | try { 20 | if (args.size() == 1){ 21 | String index = new String((byte[]) args.get(0)); 22 | if (index.equalsIgnoreCase("0")){ 23 | Protocolcode.writeString(out, "OK"); 24 | } 25 | }else { 26 | try { 27 | Protocolcode.writeError(out, "Wrong Format"); 28 | } catch (Exception e) { 29 | e.printStackTrace(); 30 | } 31 | } 32 | 33 | } catch (Exception e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | 38 | @Override 39 | public void setArgs(List args) { 40 | this.args = args; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/command/SETCommand.java: -------------------------------------------------------------------------------- 1 | package com.demo.command; 2 | 3 | import com.demo.data.DbData; 4 | import com.demo.procotol.Protocolcode; 5 | 6 | import java.io.OutputStream; 7 | import java.util.List; 8 | 9 | /** 10 | * @Author: cxx 11 | * @Date: 2019/11/3 22:30 12 | */ 13 | public class SETCommand implements ICommand { 14 | DbData dbData = DbData.getDatabase(); 15 | List args; 16 | 17 | @Override 18 | public void run(OutputStream out) { 19 | if (args.size() == 2){ 20 | String key = new String((byte[]) args.remove(0)); 21 | String value = new String((byte[]) args.remove(0)); 22 | String v = dbData.str.get(key); 23 | dbData.str.put(key, value); 24 | try { 25 | if (v == null){ 26 | Protocolcode.writeInteger(out, 1L); 27 | }else { 28 | Protocolcode.writeInteger(out, 0L); 29 | } 30 | }catch (Exception e){ 31 | e.printStackTrace(); 32 | } 33 | }else { 34 | try { 35 | Protocolcode.writeError(out, "Wrong Format"); 36 | } catch (Exception e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | } 41 | 42 | @Override 43 | public void setArgs(List args) { 44 | this.args = args; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/data/DbData.java: -------------------------------------------------------------------------------- 1 | package com.demo.data; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/11/3 20:40 8 | */ 9 | public class DbData { 10 | private static DbData dbData = new DbData(); 11 | private DbData() { 12 | } 13 | 14 | public static DbData getDatabase() { 15 | return dbData; 16 | } 17 | 18 | public static Map str = new HashMap<>(); 19 | public static Map> hash = new HashMap<>(); 20 | public static Map> list = new HashMap<>(); 21 | public static Map> set = new HashMap<>(); 22 | public static Map> zset = new HashMap<>(); 23 | 24 | public static List getList(String key) { 25 | List lists = list.computeIfAbsent(key, k -> { 26 | return new ArrayList<>(); 27 | }); 28 | return lists; 29 | } 30 | 31 | public static Set getSet(String key) { 32 | Set hashSet = set.get(key); 33 | if (hashSet == null) { 34 | hashSet = new HashSet<>(); 35 | set.put(key, hashSet); 36 | return hashSet; 37 | } 38 | return hashSet; 39 | } 40 | 41 | public static HashMap getHash(String key) { 42 | HashMap RMap = hash.get(key); 43 | if (RMap == null) { 44 | //必须创建一个列表,否则返回的是NPE,程序无法进行 45 | RMap = new HashMap<>(); 46 | hash.put(key, RMap); 47 | return RMap; 48 | } 49 | return RMap; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/exception/RedisException.java: -------------------------------------------------------------------------------- 1 | package com.demo.exception; 2 | 3 | /** 4 | * @Author: cxx 5 | * @Date: 2019/11/3 19:56 6 | */ 7 | public class RedisException extends RuntimeException{ 8 | public RedisException(String msg){ 9 | super(msg); 10 | System.out.println("Exception:" + msg); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/procotol/ProtocolInputStream.java: -------------------------------------------------------------------------------- 1 | package com.demo.procotol; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | /** 7 | * @Author: cxx 8 | * @Date: 2019/11/3 20:09 9 | * 每个Redis命令或者数据都以\r\n结尾。 10 | */ 11 | public class ProtocolInputStream { 12 | private InputStream is; 13 | 14 | public ProtocolInputStream(InputStream is) { 15 | this.is = is; 16 | } 17 | 18 | public long readInteger() throws IOException { 19 | int b = is.read(); 20 | if (b == -1) { 21 | throw new RuntimeException("不应该读到文件末尾"); 22 | } 23 | StringBuilder sb = new StringBuilder(); 24 | boolean NegativeFlag = false; 25 | if (b == '-') { 26 | NegativeFlag = true; 27 | } else { 28 | sb.append((char) b); 29 | } 30 | while (true) { 31 | b = is.read(); 32 | if (b == -1) { 33 | throw new RuntimeException("不应该读到文件末尾"); 34 | } 35 | if (b == '\r') { 36 | int c = is.read(); 37 | if (c == '\n') { 38 | break; 39 | } else { 40 | throw new RuntimeException("指令读取失败"); 41 | } 42 | } else { 43 | sb.append((char) (b)); 44 | } 45 | } 46 | long rs = Long.parseLong(sb.toString()); 47 | if (NegativeFlag) { 48 | rs = -rs; 49 | } 50 | return rs; 51 | } 52 | 53 | public String readLine() throws IOException { 54 | StringBuilder sb = new StringBuilder(); 55 | boolean flag = true; 56 | int b = 0; 57 | while (true) { 58 | if (flag) { 59 | b = is.read(); 60 | } else { 61 | flag = true; 62 | } 63 | if (b == -1) { 64 | throw new RuntimeException("不应该读到文件末尾"); 65 | 66 | } 67 | if (b == '\r') { 68 | int c = is.read(); 69 | if (c == -1) { 70 | throw new RuntimeException("不应该读到文件末尾"); 71 | } else if (c == '\n') { 72 | break; 73 | } else if (c == '\r') { 74 | sb.append((char) (b)); 75 | b = c; 76 | flag = false; 77 | } else { 78 | sb.append((char) c); 79 | } 80 | } 81 | sb.append((char) b); 82 | } 83 | return sb.toString(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /code-redis/src/main/java/com/demo/procotol/Protocolcode.java: -------------------------------------------------------------------------------- 1 | package com.demo.procotol; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.util.List; 6 | 7 | /** 8 | * @Author: cxx 9 | * @Date: 2019/11/3 20:21 10 | */ 11 | public class Protocolcode { 12 | public static void writeInteger(OutputStream write, long length) throws Exception { 13 | write.write(':'); 14 | write.write(String.valueOf(length).getBytes()); 15 | write.write("\r\n".getBytes()); 16 | write.flush(); 17 | 18 | } 19 | 20 | //'+OK\r\n' 21 | public static void writeString(OutputStream write, String str) throws Exception { 22 | write.write('+'); 23 | write.write(str.getBytes()); 24 | write.write("\r\n".getBytes()); 25 | write.flush(); 26 | } 27 | 28 | //字节流'$6\r\nfoobar\r\n' 或者 '$-1\r\n' 29 | public static void writeBulkString(OutputStream write, String str) throws Exception { 30 | byte[] b = new byte[0]; 31 | if (str != null){ 32 | b = str.getBytes(); 33 | } 34 | write.write('$'); 35 | write.write(String.valueOf(b.length).getBytes()); 36 | write.write("\r\n".getBytes()); 37 | write.write(b); 38 | write.write("\r\n".getBytes()); 39 | write.flush(); 40 | } 41 | 42 | //'2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n' 43 | public static void writeArray(OutputStream write, List list) throws Exception { 44 | write.write('*'); 45 | write.write(String.valueOf(list.size()).getBytes()); 46 | write.write("\r\n".getBytes()); 47 | for (Object o : list) { 48 | if ((o instanceof String)) { 49 | writeBulkString(write, (String) o); 50 | } else if (o instanceof Integer) { 51 | writeInteger(write, (long) o); 52 | } else if (o instanceof Long) { 53 | writeInteger(write, (Long) o); 54 | } else if (o instanceof List) { 55 | writeArray(write, (List) o); 56 | } 57 | } 58 | } 59 | 60 | //'-WRONGTYPE Operation against a key holding the wrong kind of value' 61 | public static void writeError(OutputStream write, String message) throws IOException { 62 | write.write('-'); 63 | write.write(message.getBytes()); 64 | write.write("\r\n".getBytes()); 65 | write.flush(); 66 | write.close(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /code-springaop/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.demo 13 | code-springaop 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | com.demo 31 | code-ioc 32 | 1.0-SNAPSHOT 33 | 34 | 35 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/MainTest.java: -------------------------------------------------------------------------------- 1 | package com.aop; 2 | 3 | import com.aop.core.AopBeanContext; 4 | import com.demo1.ILogService; 5 | import com.demo1.LogService; 6 | 7 | /** 8 | * @Author: cxx 9 | * @Date: 2019/10/3 11:34 10 | */ 11 | public class MainTest { 12 | public static void main(String[] args) { 13 | // 01.测试 修改ioc.properties scan.package=com.demo 14 | //IUserService userService = (IUserService) AopBeanContext.getObject(UserService.class); 15 | //userService.delete("100"); 16 | 17 | // 02.环绕通知测试 修改ioc.properties scan.package=com.demo1 18 | ILogService logService = (ILogService) AopBeanContext.getObject(LogService.class); 19 | logService.printLog("test...."); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/annotation/AdviceEnum.java: -------------------------------------------------------------------------------- 1 | package com.aop.annotation; 2 | 3 | /** 4 | * @Author: cxx 5 | * @Date: 2019/10/3 15:58 6 | * 通知方式 7 | */ 8 | public enum AdviceEnum { 9 | BEFORE("before"), 10 | AFTER("after"), 11 | AROUND("around"), 12 | AFTER_RETURNING("afterReturning"), 13 | AFTER_THROWING("afterThrowing"); 14 | 15 | AdviceEnum(String key) { 16 | this.key = key; 17 | } 18 | 19 | private String key; 20 | 21 | public String getKey() { 22 | return key; 23 | } 24 | 25 | public void setKey(String key) { 26 | this.key = key; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/annotation/MyAfter.java: -------------------------------------------------------------------------------- 1 | package com.aop.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/3 10:52 8 | * 后置通知 9 | */ 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.METHOD) 13 | public @interface MyAfter { 14 | String value(); 15 | } 16 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/annotation/MyAfterReturning.java: -------------------------------------------------------------------------------- 1 | package com.aop.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/3 10:52 8 | * 返回通知 9 | */ 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.METHOD) 13 | public @interface MyAfterReturning { 14 | String value(); 15 | } 16 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/annotation/MyAfterThrowing.java: -------------------------------------------------------------------------------- 1 | package com.aop.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/3 10:52 8 | * 异常通知 9 | */ 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.METHOD) 13 | public @interface MyAfterThrowing { 14 | String value(); 15 | } 16 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/annotation/MyAround.java: -------------------------------------------------------------------------------- 1 | package com.aop.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/3 10:52 8 | * 环绕通知 9 | */ 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.METHOD) 13 | public @interface MyAround { 14 | String value(); 15 | } 16 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/annotation/MyAspect.java: -------------------------------------------------------------------------------- 1 | package com.aop.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/3 10:52 8 | * 定义切面 9 | */ 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.TYPE) 13 | public @interface MyAspect { 14 | } 15 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/annotation/MyBefore.java: -------------------------------------------------------------------------------- 1 | package com.aop.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/3 10:52 8 | * 前置通知 9 | */ 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.METHOD) 13 | public @interface MyBefore { 14 | String value(); 15 | } 16 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/annotation/MyPointcut.java: -------------------------------------------------------------------------------- 1 | package com.aop.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/3 10:54 8 | * 切点 9 | */ 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.METHOD) 13 | public @interface MyPointcut { 14 | String value(); 15 | } 16 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/aspect/AbstractAspect.java: -------------------------------------------------------------------------------- 1 | package com.aop.aspect; 2 | 3 | 4 | /** 5 | * @Author: cxx 6 | * @Date: 2019/10/3 16:14 7 | */ 8 | public class AbstractAspect { 9 | 10 | public void before(){ 11 | 12 | } 13 | 14 | public void after(){ 15 | 16 | } 17 | 18 | public void afterReturning(Object returnVal){ 19 | 20 | } 21 | 22 | public Object around(JoinPoint joinPoint){ 23 | return null; 24 | } 25 | 26 | public void afterThrowable(Throwable e){ 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/aspect/CheckResult.java: -------------------------------------------------------------------------------- 1 | package com.aop.aspect; 2 | 3 | /** 4 | * @Author: cxx 5 | * @Date: 2019/10/3 14:50 6 | */ 7 | public class CheckResult { 8 | private boolean isRunBefore = false; 9 | private boolean isRunAfter = false; 10 | private boolean isRunAfterReturning = false; 11 | private boolean isRunAfterThrowing = false; 12 | private boolean isRunAround = false; 13 | 14 | public boolean isRunBefore() { 15 | return isRunBefore; 16 | } 17 | 18 | public void setRunBefore(boolean runBefore) { 19 | isRunBefore = runBefore; 20 | } 21 | 22 | public boolean isRunAfter() { 23 | return isRunAfter; 24 | } 25 | 26 | public void setRunAfter(boolean runAfter) { 27 | isRunAfter = runAfter; 28 | } 29 | 30 | public boolean isRunAfterReturning() { 31 | return isRunAfterReturning; 32 | } 33 | 34 | public void setRunAfterReturning(boolean runAfterReturning) { 35 | isRunAfterReturning = runAfterReturning; 36 | } 37 | 38 | public boolean isRunAfterThrowing() { 39 | return isRunAfterThrowing; 40 | } 41 | 42 | public void setRunAfterThrowing(boolean runAfterThrowing) { 43 | isRunAfterThrowing = runAfterThrowing; 44 | } 45 | 46 | public boolean isRunAround() { 47 | return isRunAround; 48 | } 49 | 50 | public void setRunAround(boolean runAround) { 51 | isRunAround = runAround; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/aspect/IAspectHandler.java: -------------------------------------------------------------------------------- 1 | package com.aop.aspect; 2 | 3 | import javafx.util.Pair; 4 | 5 | /** 6 | * @Author: cxx 7 | * @Date: 2019/10/3 14:10 8 | */ 9 | public interface IAspectHandler { 10 | /** 11 | * 获取切面实例 12 | * @param pointCanonicalName 13 | * @return 14 | */ 15 | public Pair getAspectInstance(String pointCanonicalName); 16 | } 17 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/aspect/JoinPoint.java: -------------------------------------------------------------------------------- 1 | package com.aop.aspect; 2 | 3 | /** 4 | * @Author: cxx 5 | * @Date: 2019/10/3 13:33 6 | */ 7 | public interface JoinPoint { 8 | public Object proceed(); 9 | } 10 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/core/AopBeanContext.java: -------------------------------------------------------------------------------- 1 | package com.aop.core; 2 | 3 | import com.aop.aspect.AspectHandler; 4 | import com.aop.aspect.CheckResult; 5 | import com.aop.aspect.IAspectHandler; 6 | import com.ioc.core.MyIoc; 7 | import javafx.util.Pair; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * @Author: cxx 14 | * @Date: 2019/10/3 13:45 15 | */ 16 | public class AopBeanContext { 17 | private static IAspectHandler aspectHandler = null; 18 | 19 | static { 20 | init(); 21 | } 22 | 23 | public static Object getObject(Class clz){ 24 | Object target = MyIoc.getObject(clz); 25 | if (target == null){ 26 | throw new RuntimeException("容器中获取不到实例"); 27 | } 28 | Pair aspectResult = aspectHandler.getAspectInstance(clz.getTypeName()); 29 | // 没有切面 30 | if (aspectResult == null){ 31 | return target; 32 | } 33 | // 创建代理类 34 | return ProxyBeanFactory.newProxyBean(target, aspectResult); 35 | } 36 | 37 | private static void init(){ 38 | createProxyBeanContext(MyIoc.getBeanFactory()); 39 | } 40 | 41 | // 根据切点,创建有代理类的bean容器 42 | public static void createProxyBeanContext(Map iocMap){ 43 | aspectHandler = new AspectHandler(iocMap); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/aop/core/ProxyBeanFactory.java: -------------------------------------------------------------------------------- 1 | package com.aop.core; 2 | 3 | import com.aop.aspect.CheckResult; 4 | import javafx.util.Pair; 5 | 6 | import java.lang.reflect.Proxy; 7 | 8 | /** 9 | * @Author: cxx 10 | * @Date: 2019/10/3 15:38 11 | */ 12 | public class ProxyBeanFactory { 13 | public static Object newProxyBean(Object target, Pair aspectResult){ 14 | Class[] interfaces = target.getClass().getInterfaces(); 15 | if (interfaces.length == 0){ 16 | throw new RuntimeException("proxy instance must be implements interface"); 17 | } 18 | return Proxy.newProxyInstance(target.getClass().getClassLoader(), interfaces, new BeanInvocationHandler(target, aspectResult)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/demo/Aspect.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import com.aop.annotation.*; 4 | import com.aop.aspect.AbstractAspect; 5 | import com.aop.aspect.JoinPoint; 6 | import com.ioc.annotation.MyComponent; 7 | 8 | /** 9 | * @Author: cxx 10 | * @Date: 2019/10/3 11:25 11 | * 定义切面 12 | */ 13 | @MyAspect 14 | @MyComponent 15 | public class Aspect extends AbstractAspect{ 16 | 17 | @MyPointcut("com.demo.*") 18 | private void myPointcut(){ 19 | 20 | } 21 | 22 | @MyBefore(value = "myPointcut()") 23 | public void before(){ 24 | System.out.println("前置通知...."); 25 | 26 | } 27 | 28 | @MyAfter(value = "myPointcut()") 29 | public void after(){ 30 | System.out.println("后置通知...."); 31 | 32 | } 33 | 34 | @MyAfterReturning(value = "myPointcut()") 35 | public void afterReturning(Object returnVal){ 36 | System.out.println("后置返回通知....result:" + returnVal.toString()); 37 | 38 | } 39 | 40 | @MyAround(value = "") 41 | public Object around(JoinPoint joinPoint){ 42 | System.out.println("环绕通知start...."); 43 | Object obj= joinPoint.proceed(); 44 | System.out.println("环绕通知end...."); 45 | return null; 46 | 47 | } 48 | 49 | //@MyAfterThrowing(value = "myPointcut()") 50 | public void afterThrowable(Throwable e){ 51 | System.out.println("异常通知...."); 52 | e.printStackTrace(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/demo/IUserService.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | /** 4 | * @Author: cxx 5 | * @Date: 2019/10/1 22:40 6 | */ 7 | public interface IUserService { 8 | public String delete(String id); 9 | } 10 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/demo/UserService.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | 4 | import com.ioc.annotation.MyAutowired; 5 | import com.ioc.annotation.MyComponent; 6 | 7 | /** 8 | * @Author: cxx 9 | * @Date: 2019/10/1 22:40 10 | */ 11 | @MyComponent 12 | public class UserService implements IUserService { 13 | public String delete(String id) { 14 | System.out.println("删除用户 id:" + id); 15 | int i = 1/0; 16 | return "删除成功"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/demo1/ILogService.java: -------------------------------------------------------------------------------- 1 | package com.demo1; 2 | 3 | /** 4 | * @Author: cxx 5 | * @Date: 2019/10/3 16:55 6 | */ 7 | public interface ILogService { 8 | public void printLog(String log); 9 | } 10 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/demo1/LogAspect.java: -------------------------------------------------------------------------------- 1 | package com.demo1; 2 | 3 | import com.aop.annotation.*; 4 | import com.aop.aspect.AbstractAspect; 5 | import com.aop.aspect.JoinPoint; 6 | import com.ioc.annotation.MyComponent; 7 | 8 | /** 9 | * @Author: cxx 10 | * @Date: 2019/10/3 11:25 11 | * 日志切面 12 | */ 13 | @MyAspect 14 | @MyComponent 15 | public class LogAspect extends AbstractAspect{ 16 | 17 | @MyPointcut("com.demo1.*") 18 | private void myPointcut(){ 19 | 20 | } 21 | 22 | @MyAround(value = "myPointcut()") 23 | public Object around(JoinPoint joinPoint){ 24 | Long start = System.currentTimeMillis(); 25 | System.out.println("环绕通知start...."); 26 | Object obj= joinPoint.proceed(); 27 | System.out.println("环绕通知end...."); 28 | Long end = System.currentTimeMillis(); 29 | System.out.println("执行方法耗时:" + String.valueOf(end - start)); 30 | return obj; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /code-springaop/src/main/java/com/demo1/LogService.java: -------------------------------------------------------------------------------- 1 | package com.demo1; 2 | 3 | import com.ioc.annotation.MyComponent; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * @Author: cxx 9 | * @Date: 2019/10/3 16:56 10 | */ 11 | @MyComponent 12 | public class LogService implements ILogService { 13 | @Override 14 | public void printLog(String log) { 15 | System.out.println("日志打印成功 :" + log); 16 | try { 17 | TimeUnit.SECONDS.sleep(1); 18 | } catch (InterruptedException e) { 19 | e.printStackTrace(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /code-springaop/src/main/resources/ioc.properties: -------------------------------------------------------------------------------- 1 | scan.package=com.demo1 -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.demo 8 | sourcecode 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | code-proxy 13 | code-springaop 14 | code-ioc 15 | study-io 16 | study-chat 17 | code-netty-tomcat 18 | code-netty 19 | study-transcation 20 | study-uml 21 | code-redis 22 | study-cache 23 | study-redis 24 | study-net 25 | study-zk 26 | study-algorithm 27 | study-other 28 | 29 | 30 | 31 | 32 | 33 | cn.hutool 34 | hutool-all 35 | 4.6.1 36 | 37 | 38 | org.projectlombok 39 | lombok 40 | 1.18.4 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /study-algorithm/README.MD: -------------------------------------------------------------------------------- 1 | ## 算法学习 2 | 基于java语言的关于数据结构的代码实现 3 | 4 | ---- 5 | 6 | ## 数据结构分类 7 | > 1.数组Array 8 | > 2.栈Stack 9 | > 3.队列Queue 10 | > 4.链表LinkedList 11 | > 5.树Tree 12 | > 6.散列表Hash 13 | > 7.堆Heap 14 | > 8.图Graph 15 | 16 | --- 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /study-algorithm/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | study-algorithm 13 | 14 | 15 | 16 | cn.hutool 17 | hutool-all 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/demo/array/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: lanxinghua 3 | * Date: 2019/11/20 11:58 4 | * Desc: 5 | */ 6 | package com.demo.array; 7 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/demo/graph/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: lanxinghua 3 | * Date: 2019/11/20 11:58 4 | * Desc: 5 | */ 6 | package com.demo.graph; 7 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/demo/hash/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: lanxinghua 3 | * Date: 2019/11/20 11:58 4 | * Desc: 5 | */ 6 | package com.demo.hash; 7 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/demo/heap/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: lanxinghua 3 | * Date: 2019/11/20 11:58 4 | * Desc: 5 | */ 6 | package com.demo.heap; 7 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/demo/list/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: lanxinghua 3 | * Date: 2019/11/20 11:59 4 | * Desc: 5 | */ 6 | package com.demo.list; 7 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/demo/queue/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: lanxinghua 3 | * Date: 2019/11/20 11:59 4 | * Desc: 5 | */ 6 | package com.demo.queue; 7 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/demo/stack/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: lanxinghua 3 | * Date: 2019/11/20 11:59 4 | * Desc: 5 | */ 6 | package com.demo.stack; 7 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/demo/string/DelStr.java: -------------------------------------------------------------------------------- 1 | package com.demo.string; 2 | 3 | /** 4 | * User: lanxinghua 5 | * Date: 2019/11/20 14:51 6 | * Desc: 用于删除与指定字符串匹配的子串 7 | */ 8 | public class DelStr { 9 | public static void main(String[] args) { 10 | String target = "ababdabcxxcdabcabc"; 11 | String pattern = "cxx"; 12 | System.out.println(deleteAll(target, pattern)); 13 | } 14 | 15 | // 返回将target串中所有与pattern匹配的子串删除后的字符串 16 | public static String deleteAll(String target, String pattern) { 17 | int i = target.indexOf(pattern); 18 | while (i != -1) { 19 | target = target.substring(0, i) 20 | + target.substring(i + pattern.length()); 21 | i = target.indexOf(pattern, i); 22 | } 23 | return target; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/demo/tree/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: lanxinghua 3 | * Date: 2019/11/20 11:59 4 | * Desc: 5 | */ 6 | package com.demo.tree; 7 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/sort/BubbleSort.java: -------------------------------------------------------------------------------- 1 | package com.sort; 2 | 3 | import cn.hutool.json.JSONUtil; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/11/20 18:11 8 | * Desc: 冒泡排序 9 | */ 10 | public class BubbleSort { 11 | public static void main(String[] args) { 12 | int[] nums = {1,4,9,10,3,5}; 13 | System.out.println("排序前:" + JSONUtil.toJsonStr(nums)); 14 | System.out.println("排序后:"+ JSONUtil.toJsonStr(sort(nums))); 15 | 16 | } 17 | 18 | private static int[] sort(int[] nums){ 19 | int times = nums.length -1; 20 | // 循环次数 21 | for (int i = 0; i < times; i++) { 22 | System.out.println("第" + (i+1) +"趟...."); 23 | // 循环替换元素 24 | for (int j = 0; j < times - i; j++) { 25 | if (nums[j] > nums[j+1]){ 26 | System.out.println("交换:" + nums[j] + "-" + nums[j+1]); 27 | int temp = nums[j]; 28 | nums[j] = nums[j+1]; 29 | nums[j+1] = temp; 30 | } 31 | } 32 | } 33 | return nums; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/sort/InsertSort.java: -------------------------------------------------------------------------------- 1 | package com.sort; 2 | 3 | import cn.hutool.json.JSONUtil; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/11/20 19:27 8 | * Desc: 插入排序 9 | */ 10 | public class InsertSort { 11 | 12 | public static void main(String[] args) { 13 | int[] nums = {1,4,9,10,3,5}; 14 | System.out.println("排序前:" + JSONUtil.toJsonStr(nums)); 15 | System.out.println("排序后:"+ JSONUtil.toJsonStr(sort(nums))); 16 | } 17 | 18 | private static int[] sort(int[] nums){ 19 | // 对下标为1元素进行插入,下标为0元素默认是有序的 20 | for (int i = 1; i < nums.length; i++) { 21 | int currValue = nums[i]; 22 | int position = i; 23 | // 对已排序的元素从右往左扫描 24 | for (int j = i - 1; j >= 0; j--){ 25 | if (nums[j] > currValue){ 26 | // 未排序值确定,插入位置向前移动 27 | nums[j+1] = nums[j]; 28 | position -=1; 29 | }else { 30 | break; 31 | } 32 | } 33 | 34 | // 值插入的位置 35 | nums[position] = currValue; 36 | } 37 | return nums; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/sort/QuickSort.java: -------------------------------------------------------------------------------- 1 | package com.sort; 2 | 3 | import cn.hutool.json.JSONUtil; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/11/20 20:13 8 | * Desc: 快速排序 9 | * 排序前:[1,4,9,10,3,5] 10 | * 基数定为:1 11 | * 分界点位置:0 分界点值:1 12 | * 13 | * 基数定为:4 14 | * 分界点位置:2 分界点值:9 15 | * 16 | * 基数定为:10 17 | * 分界点位置:5 分界点值:5 18 | * 19 | * 基数定为:5 20 | * 分界点位置:3 分界点值:5 21 | * 22 | * 排序后:[1,3,4,5,9,10] 23 | */ 24 | public class QuickSort { 25 | 26 | public static void main(String[] args) { 27 | int[] nums = {1,4,9,10,3,5}; 28 | System.out.println("排序前:" + JSONUtil.toJsonStr(nums)); 29 | quickSort(nums, 0, nums.length -1); 30 | System.out.println("排序后:"+ JSONUtil.toJsonStr(nums)); 31 | } 32 | 33 | // 假设从小到大 34 | private static int[] quickSort(int[] nums, int low, int high){ 35 | if (low < high){ 36 | int part = partition(nums, low, high); 37 | // 递归调用 38 | quickSort(nums, low, part -1); 39 | quickSort(nums, part+1, high); 40 | } 41 | 42 | return nums; 43 | } 44 | 45 | // 切分方法 46 | private static int partition(int[] nums, int low, int high){ 47 | // 先基准数 48 | int base = nums[low]; 49 | System.out.println("基数定为:" + base); 50 | // 两端交替向内扫描 51 | while (low < high){ 52 | while (low < high && nums[high] >= base){ 53 | high--; 54 | } 55 | // 将比基数小的数向低端移 56 | nums[low] = nums[high]; 57 | 58 | while (low < high && nums[low] <= base){ 59 | low++; 60 | } 61 | // 将比基数大的数向高端移 62 | nums[high] = nums[low]; 63 | } 64 | // 设置基数 65 | System.out.println("分界点位置:" + low + " 分界点值:" + nums[low]); 66 | System.out.println(); 67 | nums[low] = base; 68 | return low; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /study-algorithm/src/main/java/com/sort/SelectionSort.java: -------------------------------------------------------------------------------- 1 | package com.sort; 2 | 3 | import cn.hutool.json.JSONUtil; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/11/20 18:32 8 | * Desc: 选择排序 9 | */ 10 | public class SelectionSort { 11 | public static void main(String[] args) { 12 | int[] nums = {1,4,9,10,3,5}; 13 | System.out.println("排序前:" + JSONUtil.toJsonStr(nums)); 14 | System.out.println("排序后:"+ JSONUtil.toJsonStr(sort(nums))); 15 | 16 | } 17 | 18 | private static int[] sort(int[] nums){ 19 | // N-1轮比较 20 | for (int i = 0; i < nums.length -1 ; i++) { 21 | int min = i; 22 | // 每轮需要N-1次比较 23 | for (int j = i + 1; j < nums.length; j++) { 24 | if (nums[j] < nums[min]){ 25 | // 找到最小坐标 26 | min = j; 27 | } 28 | } 29 | 30 | // 判断最小值是否有改动,进行替换 31 | if (min != i){ 32 | int temp = nums[i]; 33 | nums[i] = nums[min]; 34 | nums[min] = temp; 35 | } 36 | } 37 | return nums; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /study-cache/README.MD: -------------------------------------------------------------------------------- 1 | ## 自己实现简单Java缓存 2 | #### 需求 3 | > 1.数据共享 4 | > 2.过期自动失效 5 | 6 | #### 实现思路 7 | 采用HashMap+定时器线程池实现,map用于存储键值对数据,map的value是Cache的内部类对 8 | 象Entity,Entity包含value和该键值对的生命周期定时器Future。 9 | --- 10 | -------------------------------------------------------------------------------- /study-cache/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.demo 13 | study-cache 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /study-cache/src/main/java/com/demo/ICache.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | /** 4 | * @Author: cxx 5 | * @Date: 2019/11/3 18:00 6 | */ 7 | public interface ICache { 8 | public void put(String key, Object value); 9 | 10 | public void put(String key, Object value, Long secondExpire); 11 | 12 | public T get(String key); 13 | 14 | public T remove(String key); 15 | } 16 | -------------------------------------------------------------------------------- /study-chat/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/img/1.jpg -------------------------------------------------------------------------------- /study-chat/img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/img/2.jpg -------------------------------------------------------------------------------- /study-chat/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.demo 13 | study-chat 14 | 15 | 16 | 17 | io.netty 18 | netty-all 19 | 4.1.31.Final 20 | 21 | 22 | com.alibaba 23 | fastjson 24 | 1.2.45 25 | 26 | 27 | cn.hutool 28 | hutool-all 29 | 30 | 31 | 32 | 33 | org.msgpack 34 | msgpack 35 | 0.6.12 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-compiler-plugin 44 | 45 | 8 46 | 8 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /study-chat/src/main/java/com/demo/client/ChatClient.java: -------------------------------------------------------------------------------- 1 | package com.demo.client; 2 | 3 | import com.demo.protocol.IMDecoder; 4 | import com.demo.protocol.IMEncoder; 5 | import io.netty.bootstrap.Bootstrap; 6 | import io.netty.channel.ChannelFuture; 7 | import io.netty.channel.ChannelInitializer; 8 | import io.netty.channel.ChannelOption; 9 | import io.netty.channel.EventLoopGroup; 10 | import io.netty.channel.nio.NioEventLoopGroup; 11 | import io.netty.channel.socket.SocketChannel; 12 | import io.netty.channel.socket.nio.NioSocketChannel; 13 | 14 | /** 15 | * User: lanxinghua 16 | * Date: 2019/10/14 09:19 17 | * Desc: 18 | */ 19 | public class ChatClient { 20 | private String host; 21 | private int port; 22 | 23 | public ChatClient(String host, int port) { 24 | this.host = host; 25 | this.port = port; 26 | } 27 | 28 | public void start(String nickName){ 29 | EventLoopGroup workGroup = new NioEventLoopGroup(); 30 | try { 31 | Bootstrap bootstrap = new Bootstrap(); 32 | bootstrap.group(workGroup) 33 | .channel(NioSocketChannel.class) 34 | .option(ChannelOption.SO_KEEPALIVE, true) 35 | .handler(new ChannelInitializer() { 36 | @Override 37 | protected void initChannel(SocketChannel s) { 38 | s.pipeline().addLast(new IMDecoder()); 39 | s.pipeline().addLast(new IMEncoder()); 40 | s.pipeline().addLast(new ChatClientHandler(nickName)); 41 | } 42 | }); 43 | ChannelFuture f = bootstrap.connect(host, port).sync(); 44 | f.channel().closeFuture().sync(); 45 | }catch (Exception e){ 46 | e.printStackTrace(); 47 | }finally { 48 | workGroup.shutdownGracefully(); 49 | } 50 | } 51 | 52 | public static void main(String[] args) { 53 | // 实现跨平台,直接和web用户进行沟通 54 | new ChatClient("localhost", 8080).start("socketUser"); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /study-chat/src/main/java/com/demo/client/ChatClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.demo.client; 2 | 3 | import cn.hutool.log.Log; 4 | import cn.hutool.log.LogFactory; 5 | import com.demo.protocol.IMMessage; 6 | import com.demo.protocol.IMP; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.channel.ChannelInboundHandlerAdapter; 9 | 10 | import java.util.Scanner; 11 | 12 | /** 13 | * User: lanxinghua 14 | * Date: 2019/10/14 09:20 15 | * Desc: 16 | */ 17 | public class ChatClientHandler extends ChannelInboundHandlerAdapter { 18 | private static final Log log = LogFactory.get(ChatClientHandler.class); 19 | private String nickName; 20 | private ChannelHandlerContext ctx; 21 | 22 | public ChatClientHandler(String nickName) { 23 | this.nickName = nickName; 24 | } 25 | 26 | @Override 27 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 28 | IMMessage message = (IMMessage) msg; 29 | log.info("收到消息:" + message.toString()); 30 | } 31 | 32 | private boolean sendMsg(IMMessage msg){ 33 | ctx.channel().writeAndFlush(msg); 34 | log.info("已发送至聊天面板,请继续输入"); 35 | return msg.getCmd().equals(IMP.LOGOUT.getName()) ? false : true; 36 | } 37 | 38 | 39 | private void session(){ 40 | new Thread(() -> { 41 | System.out.println(nickName +"你好,请在控制台输入指令:"); 42 | IMMessage msg = null; 43 | Scanner scanner = new Scanner(System.in); 44 | do{ 45 | if (scanner.hasNext()){ 46 | String cmd = scanner.nextLine(); 47 | if ("exit".equalsIgnoreCase(cmd)){ 48 | msg = new IMMessage(IMP.LOGOUT.getName(), System.currentTimeMillis(), nickName); 49 | }else { 50 | msg = new IMMessage(IMP.CHAT.getName(), System.currentTimeMillis(), nickName, cmd); 51 | } 52 | } 53 | }while (sendMsg(msg)); 54 | }).start(); 55 | } 56 | 57 | @Override 58 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 59 | this.ctx = ctx; 60 | IMMessage message = new IMMessage(IMP.LOGIN.getName(), System.currentTimeMillis(), nickName); 61 | sendMsg(message); 62 | log.info("登陆成功"); 63 | session(); 64 | } 65 | 66 | @Override 67 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 68 | log.info("与服务器断开连接:"+cause.getMessage()); 69 | ctx.close(); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /study-chat/src/main/java/com/demo/protocol/IMEncoder.java: -------------------------------------------------------------------------------- 1 | package com.demo.protocol; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.MessageToByteEncoder; 6 | import org.msgpack.MessagePack; 7 | 8 | 9 | /** 10 | * User: lanxinghua 11 | * Date: 2019/10/10 16:46 12 | * Desc: 13 | */ 14 | public class IMEncoder extends MessageToByteEncoder { 15 | @Override 16 | protected void encode(ChannelHandlerContext ctx, IMMessage msg, ByteBuf byteBuf) throws Exception { 17 | byteBuf.writeBytes(new MessagePack().write(msg)); 18 | } 19 | 20 | // 对msg进行格式化 21 | public String encode(IMMessage msg){ 22 | if(null == msg){ return ""; } 23 | String prex = "[" + msg.getCmd() + "]" + "[" + msg.getTime() + "]"; 24 | if(IMP.LOGIN.getName().equals(msg.getCmd()) || 25 | IMP.CHAT.getName().equals(msg.getCmd()) || 26 | IMP.FLOWER.getName().equals(msg.getCmd())){ 27 | prex += ("[" + msg.getSender() + "]"); 28 | }else if(IMP.SYSTEM.getName().equals(msg.getCmd())){ 29 | prex += ("[" + msg.getOnlineCount() + "]"); 30 | } 31 | if(!(null == msg.getMsg() || "".equals(msg.getMsg()))){ 32 | prex += (" - " + msg.getMsg()); 33 | } 34 | return prex; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /study-chat/src/main/java/com/demo/protocol/IMMessage.java: -------------------------------------------------------------------------------- 1 | package com.demo.protocol; 2 | 3 | import org.msgpack.annotation.Message; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/10/10 16:46 8 | * Desc: 自定义消息实体类 9 | */ 10 | @Message 11 | public class IMMessage { 12 | // ip地址 13 | private String addr; 14 | 15 | // 命令类型 @IMP.name 16 | private String cmd; 17 | 18 | // 命令发送时间 19 | private long time; 20 | 21 | // 当前在线人数 22 | private int onlineCount; 23 | 24 | // 发送人 25 | private String sender; 26 | 27 | // 接收人 28 | private String receiver; 29 | 30 | // 消息内容 31 | private String msg; 32 | 33 | public IMMessage(){} 34 | 35 | 36 | public IMMessage(String cmd, long time, int onlineCount, String msg) { 37 | this.cmd = cmd; 38 | this.time = time; 39 | this.onlineCount = onlineCount; 40 | this.msg = msg; 41 | } 42 | 43 | public IMMessage(String cmd, long time, String sender){ 44 | this.cmd = cmd; 45 | this.time = time; 46 | this.sender = sender; 47 | } 48 | 49 | public IMMessage(String cmd, long time, String sender, String msg){ 50 | this.cmd = cmd; 51 | this.time = time; 52 | this.sender = sender; 53 | this.msg = msg; 54 | } 55 | 56 | public String getAddr() { 57 | return addr; 58 | } 59 | 60 | public void setAddr(String addr) { 61 | this.addr = addr; 62 | } 63 | 64 | public String getCmd() { 65 | return cmd; 66 | } 67 | 68 | public void setCmd(String cmd) { 69 | this.cmd = cmd; 70 | } 71 | 72 | public long getTime() { 73 | return time; 74 | } 75 | 76 | public void setTime(long time) { 77 | this.time = time; 78 | } 79 | 80 | public int getOnlineCount() { 81 | return onlineCount; 82 | } 83 | 84 | public void setOnlineCount(int onlineCount) { 85 | this.onlineCount = onlineCount; 86 | } 87 | 88 | public String getSender() { 89 | return sender; 90 | } 91 | 92 | public void setSender(String sender) { 93 | this.sender = sender; 94 | } 95 | 96 | public String getReceiver() { 97 | return receiver; 98 | } 99 | 100 | public void setReceiver(String receiver) { 101 | this.receiver = receiver; 102 | } 103 | 104 | public String getMsg() { 105 | return msg; 106 | } 107 | 108 | public void setMsg(String msg) { 109 | this.msg = msg; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /study-chat/src/main/java/com/demo/protocol/IMP.java: -------------------------------------------------------------------------------- 1 | package com.demo.protocol; 2 | 3 | import org.msgpack.annotation.Message; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/10/10 16:55 8 | * Desc: instant messaging protocol即时通讯协议 9 | */ 10 | public enum IMP { 11 | SYSTEM("SYSTEM", "系统消息"), 12 | LOGIN("LOGIN", "登陆"), 13 | LOGOUT("LOGOUT", "登出"), 14 | CHAT("CHAT", "聊天"), 15 | FLOWER("FLOWER", "送鲜花") 16 | ; 17 | 18 | private String name; 19 | private String desc; 20 | 21 | IMP(String name, String desc) { 22 | this.name = name; 23 | this.desc = desc; 24 | } 25 | 26 | public static IMP getInstance(String name){ 27 | for (IMP value : IMP.values()) { 28 | if (value.getName().equalsIgnoreCase(name)){ 29 | return value; 30 | } 31 | } 32 | return null; 33 | } 34 | 35 | public static boolean isIMP(String content){ 36 | return content.matches("^\\[(SYSTEM|LOGIN|LOGIN|CHAT)\\]"); 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | public String getDesc() { 48 | return desc; 49 | } 50 | 51 | public void setDesc(String desc) { 52 | this.desc = desc; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /study-chat/src/main/java/com/demo/server/handler/SocketHandler.java: -------------------------------------------------------------------------------- 1 | package com.demo.server.handler; 2 | 3 | import cn.hutool.log.Log; 4 | import cn.hutool.log.LogFactory; 5 | import com.demo.processor.MsgProcessor; 6 | import com.demo.protocol.IMMessage; 7 | import io.netty.channel.Channel; 8 | import io.netty.channel.ChannelHandlerContext; 9 | import io.netty.channel.SimpleChannelInboundHandler; 10 | 11 | /** 12 | * User: lanxinghua 13 | * Date: 2019/10/10 16:36 14 | * Desc: 15 | */ 16 | public class SocketHandler extends SimpleChannelInboundHandler { 17 | private static Log LOG = LogFactory.get(SocketHandler.class); 18 | private MsgProcessor processor = new MsgProcessor(); 19 | 20 | @Override 21 | protected void channelRead0(ChannelHandlerContext ctx, IMMessage msg) throws Exception { 22 | processor.sendMsg(ctx.channel(), msg); 23 | } 24 | 25 | 26 | @Override 27 | public void handlerAdded(ChannelHandlerContext ctx) throws Exception { 28 | LOG.info("Socket创建..."); 29 | super.handlerAdded(ctx); 30 | } 31 | 32 | @Override 33 | public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { 34 | Channel client = ctx.channel(); 35 | processor.logout(client); 36 | LOG.info("Socket Client:" + processor.getNickName(client) + "离开"); 37 | } 38 | 39 | @Override 40 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 41 | LOG.info("channelInactive"); 42 | super.channelInactive(ctx); 43 | } 44 | /** 45 | * tcp链路建立成功后调用 46 | */ 47 | @Override 48 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 49 | LOG.info("Socket Client: 有客户端连接:"+ processor.getAddress(ctx.channel())); 50 | } 51 | 52 | /** 53 | * 异常处理 54 | */ 55 | @Override 56 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 57 | LOG.info("Socket Client: 与客户端断开连接:"+cause.getMessage()); 58 | cause.printStackTrace(); 59 | ctx.close(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /study-chat/src/main/resources/web.properties: -------------------------------------------------------------------------------- 1 | application.name=web 2 | -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/1.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/10.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/100.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/100.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/101.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/101.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/102.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/102.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/103.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/103.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/104.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/104.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/105.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/105.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/106.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/106.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/107.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/107.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/108.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/108.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/109.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/109.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/11.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/110.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/110.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/111.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/111.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/112.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/112.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/113.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/113.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/114.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/114.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/115.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/115.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/116.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/116.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/117.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/117.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/118.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/118.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/119.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/119.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/12.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/120.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/120.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/121.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/121.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/122.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/122.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/123.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/123.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/124.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/124.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/125.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/125.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/126.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/126.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/127.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/127.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/128.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/128.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/129.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/129.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/13.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/13.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/130.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/130.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/14.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/15.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/15.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/16.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/17.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/17.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/18.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/19.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/19.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/2.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/20.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/21.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/21.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/22.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/22.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/23.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/23.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/24.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/25.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/25.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/26.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/26.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/27.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/27.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/28.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/28.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/29.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/3.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/30.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/30.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/31.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/32.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/32.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/33.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/33.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/34.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/34.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/35.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/35.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/36.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/36.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/37.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/37.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/38.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/38.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/39.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/39.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/4.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/40.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/40.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/41.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/41.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/42.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/42.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/43.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/43.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/44.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/44.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/45.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/45.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/46.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/46.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/47.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/47.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/48.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/48.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/49.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/49.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/5.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/50.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/50.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/51.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/51.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/52.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/52.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/53.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/53.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/54.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/54.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/55.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/55.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/56.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/56.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/57.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/57.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/58.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/58.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/59.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/59.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/6.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/60.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/60.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/61.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/61.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/62.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/62.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/63.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/63.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/64.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/64.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/65.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/65.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/66.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/66.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/67.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/67.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/68.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/68.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/69.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/69.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/7.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/70.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/70.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/71.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/71.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/72.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/72.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/73.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/73.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/74.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/74.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/75.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/75.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/76.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/76.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/77.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/77.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/78.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/78.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/79.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/79.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/8.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/80.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/80.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/81.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/81.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/82.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/82.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/83.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/83.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/84.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/84.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/85.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/85.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/86.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/86.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/87.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/87.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/88.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/88.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/89.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/89.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/9.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/90.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/90.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/91.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/91.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/92.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/92.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/93.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/93.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/94.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/94.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/95.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/95.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/96.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/96.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/97.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/97.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/98.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/98.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/face/99.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/face/99.gif -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/icon/face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/icon/face.png -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/icon/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/icon/file.png -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/icon/flower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/icon/flower.png -------------------------------------------------------------------------------- /study-chat/src/main/resources/webroot/images/icon/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/study-chat/src/main/resources/webroot/images/icon/img.png -------------------------------------------------------------------------------- /study-io/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.demo 13 | study-io 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 20 | 1.7 21 | 1.7 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /study-io/src/main/java/com/demo/aio/AioClient.java: -------------------------------------------------------------------------------- 1 | package com.demo.aio; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.nio.ByteBuffer; 6 | import java.nio.channels.AsynchronousSocketChannel; 7 | import java.nio.channels.CompletionHandler; 8 | 9 | /** 10 | * @Author: cxx 11 | * @Date: 2019/10/6 12:49 12 | */ 13 | public class AioClient { 14 | private AsynchronousSocketChannel channel; 15 | private String host; 16 | private int port; 17 | 18 | public AioClient(String host, int port) { 19 | this.host = host; 20 | this.port = port; 21 | try { 22 | channel = AsynchronousSocketChannel.open(); 23 | } catch (IOException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | 28 | private void listener(){ 29 | // 这里只做写操作 30 | channel.connect(new InetSocketAddress(host, port), null, new CompletionHandler() { 31 | @Override 32 | public void completed(Void result, Object attachment) { 33 | try { 34 | channel.write(ByteBuffer.wrap("测试....发送消息....".getBytes())).get(); 35 | }catch (Exception e){ 36 | e.printStackTrace(); 37 | } 38 | } 39 | 40 | @Override 41 | public void failed(Throwable exc, Object attachment) { 42 | exc.printStackTrace(); 43 | } 44 | }); 45 | 46 | // 读操作 47 | final ByteBuffer readBuf = ByteBuffer.allocate(1024); 48 | channel.read(readBuf, null, new CompletionHandler() { 49 | @Override 50 | public void completed(Integer result, Object attachment) { 51 | System.out.println("服务端响应结果:" + new String(readBuf.array())); 52 | } 53 | 54 | @Override 55 | public void failed(Throwable exc, Object attachment) { 56 | exc.printStackTrace(); 57 | } 58 | }); 59 | try { 60 | Thread.sleep(Integer.MAX_VALUE); 61 | } catch (InterruptedException ex) { 62 | System.out.println(ex); 63 | } 64 | } 65 | 66 | public static void main(String[] args) { 67 | new AioClient("localhost", 8080).listener(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /study-io/src/main/java/com/demo/bio/BioClient.java: -------------------------------------------------------------------------------- 1 | package com.demo.bio; 2 | 3 | import java.io.IOException; 4 | import java.io.ObjectInputStream; 5 | import java.io.ObjectOutputStream; 6 | import java.net.Socket; 7 | 8 | /** 9 | * @Author: cxx 10 | * @Date: 2019/10/6 11:25 11 | */ 12 | public class BioClient { 13 | private String host; 14 | private int port; 15 | private Socket socket; 16 | 17 | public BioClient(String host, int port) { 18 | this.host = host; 19 | this.port = port; 20 | } 21 | 22 | public void listener(){ 23 | try { 24 | socket = new Socket(host, port); 25 | ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 26 | oos.writeObject("客户端向服务器发送信息"); 27 | oos.flush(); 28 | ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 29 | Object result = ois.readUTF(); 30 | System.out.println("服务器响应:" + result.toString()); 31 | ois.close(); 32 | oos.close(); 33 | }catch (Exception e){ 34 | e.printStackTrace(); 35 | }finally { 36 | if (socket != null){ 37 | try { 38 | socket.close(); 39 | } catch (IOException e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | } 44 | } 45 | 46 | public static void main(String[] args) { 47 | new BioClient("localhost", 8080).listener(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /study-io/src/main/java/com/demo/bio/BioServer.java: -------------------------------------------------------------------------------- 1 | package com.demo.bio; 2 | 3 | import java.io.ObjectInputStream; 4 | import java.io.ObjectOutputStream; 5 | import java.net.ServerSocket; 6 | import java.net.Socket; 7 | 8 | /** 9 | * @Author: cxx 10 | * @Date: 2019/10/6 11:26 11 | */ 12 | public class BioServer { 13 | private int port; 14 | private Socket client; 15 | 16 | public BioServer(int port) { 17 | this.port = port; 18 | } 19 | 20 | public void listener(){ 21 | try { 22 | System.out.println("服务端开启,等待连接....."); 23 | ServerSocket socket = new ServerSocket(port); 24 | client = socket.accept(); 25 | 26 | ObjectInputStream ois = new ObjectInputStream(client.getInputStream()); 27 | Object result = ois.readObject(); 28 | System.out.println("接收信息:" + result.toString()); 29 | 30 | ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream()); 31 | oos.writeUTF("服务器发送消息,欢迎你"); 32 | oos.flush(); 33 | oos.close(); 34 | }catch (Exception e){ 35 | e.printStackTrace(); 36 | }finally { 37 | if (client != null){ 38 | try { 39 | client.close(); 40 | }catch (Exception e){ 41 | e.printStackTrace(); 42 | } 43 | } 44 | } 45 | } 46 | 47 | public static void main(String[] args) { 48 | new BioServer(8080).listener(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /study-net/README.MD: -------------------------------------------------------------------------------- 1 | ## 网络相关学习代码 2 | 3 | --- 4 | #### 一、实现长连接+心跳检查 5 | 长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的。如果,长时间未发送维持连接包,服务端程序将断开连接。 6 | 7 | 客户端: 8 | > 1.Client通过持有Socket的对象,可以发送Massage Object(消息)给服务端。 9 | > 2.如果keepAliveDelay 2秒内未发送任何数据,则自动发送一个KeepAlive(心跳)给服务端,用于维持连接。 10 | 11 | 服务端: 12 | > 1.由于客户端会定时(keepAliveDelay毫秒)发送维持连接的信息过来,所以,服务端要有一个检测机制。 13 | > 2.当服务端receiveTimeDelay毫秒(程序中是3秒)内未接收任何数据,则自动断开与客户端的连接。 14 | 15 | --- 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /study-net/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | study-net 13 | 14 | 15 | 16 | commons-net 17 | commons-net 18 | 3.6 19 | 20 | 21 | 22 | 23 | 24 | org.apache.maven.plugins 25 | maven-compiler-plugin 26 | 27 | 1.8 28 | 1.8 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /study-net/src/main/java/com/demo/longconn/ClientTest.java: -------------------------------------------------------------------------------- 1 | package com.demo.longconn; 2 | 3 | import com.demo.longconn.client.Client; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/11/4 19:32 8 | * Desc: 9 | */ 10 | public class ClientTest { 11 | public static void main(String[] args) { 12 | for (int i = 1; i <=3; i++) { 13 | new Client("localhost", 9999, "客户端" + i).start(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /study-net/src/main/java/com/demo/longconn/KeepAlive.java: -------------------------------------------------------------------------------- 1 | package com.demo.longconn; 2 | 3 | import java.io.Serializable; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Date; 6 | 7 | /** 8 | * User: lanxinghua 9 | * Date: 2019/11/4 18:45 10 | * Desc: 维持连接的消息对象,心跳对象 11 | */ 12 | public class KeepAlive implements Serializable { 13 | private String clientName; 14 | 15 | public KeepAlive(String clientName) { 16 | this.clientName = clientName; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\t维持连接包"; 22 | } 23 | 24 | public String getClientName() { 25 | return clientName; 26 | } 27 | 28 | public void setClientName(String clientName) { 29 | this.clientName = clientName; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /study-net/src/main/java/com/demo/longconn/ServerTest.java: -------------------------------------------------------------------------------- 1 | package com.demo.longconn; 2 | 3 | import com.demo.longconn.server.Server; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/11/4 19:32 8 | * Desc: 9 | */ 10 | public class ServerTest { 11 | public static void main(String[] args) { 12 | new Server(9999).start(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /study-net/src/main/java/com/demo/longconn/server/ClientState.java: -------------------------------------------------------------------------------- 1 | package com.demo.longconn.server; 2 | 3 | /** 4 | * @Author: cxx 5 | * @Date: 2019/11/4 22:34 6 | * 客户端服务器状态 7 | */ 8 | public class ClientState { 9 | private int isValid = 0; 10 | private String clientName; 11 | private long lastReTime; 12 | 13 | public int getIsValid() { 14 | return isValid; 15 | } 16 | 17 | public void setIsValid(int isValid) { 18 | this.isValid = isValid; 19 | } 20 | 21 | public String getClientName() { 22 | return clientName; 23 | } 24 | 25 | public void setClientName(String clientName) { 26 | this.clientName = clientName; 27 | } 28 | 29 | public long getLastReTime() { 30 | return lastReTime; 31 | } 32 | 33 | public void setLastReTime(long lastReTime) { 34 | this.lastReTime = lastReTime; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "ClientState{" + 40 | "isValid=" + isValid + 41 | ", clientName='" + clientName + '\'' + 42 | ", lastReTime=" + lastReTime + 43 | '}'; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /study-other/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | study-other 13 | 14 | 15 | 16 | org.apache.maven.plugins 17 | maven-compiler-plugin 18 | 19 | 7 20 | 7 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /study-other/src/main/java/com/jvm/CpuTest.java: -------------------------------------------------------------------------------- 1 | package com.jvm; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * User: lanxinghua 10 | * Date: 2019/11/21 18:14 11 | * Desc: 12 | */ 13 | public class CpuTest { 14 | public static void main(String[] args) { 15 | List list = new ArrayList<>(); 16 | while (true){ 17 | HashMap map = new HashMap<>(); 18 | map.put("key", new Object()); 19 | list.add(map); 20 | if (list.size() > 3000000){ 21 | System.out.println("clean"); 22 | list.clear(); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /study-redis/README.MD: -------------------------------------------------------------------------------- 1 | ## REDIS学习相关代码 2 | 3 | ## 一、redis实现消息队列 4 | > 1.点对点 push/pop:一条消息只能被一个消费者接受 RedisQueueTest 5 | > 2.发布订阅 pub/sub 6 | 7 | --- 8 | 9 | ## 二、自己实现心跳检测 10 | #### 2.1 2种可实现的方式 11 | > 1.轮询机制:服务端定时主动的去与要监控状态的客户端,客户端没有返回或返回错误、失效信息、则认为客户端已经宕机。 12 | > 2.心跳机制:服务端保存所有客户端的状态信息,然后等待客户端定时来访问服务端,更新当前状态,如果客户端超过指定的时间没有来更新状态,则认为客户端已经宕机或者其状态异常。 13 | 14 | 采用的是心跳,这样一是避免服务端的压力,二是灵活好控制 15 | 16 | #### 2.2 实现思路 17 | 客户端启动后,带着自己的标识符与服务端建立socket连接,服务端缓存下来对应信息,然后在通过socket流,定时发送当前信息消息到服务端某个接口,服务端收到后更新当前的客户端 18 | 的状态,比如(会话地址,标识符,网络的活跃状态,连接时间,心跳时间),本次来更新的时间就是心跳时间,然后服务端还有一个定时器,定时检查所有缓存的客户端会话集合,将其中 19 | 心跳时间与当前时间进行对比,如果超过指定的时间还没有来更新则认为该客户端的网络出现异常或者宕机,然后更新该客户端的网络状态。 20 | --- 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /study-redis/src/main/java/com/demo/RedisApplication.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * User: lanxinghua 8 | * Date: 2019/11/4 15:25 9 | * Desc: 10 | */ 11 | @SpringBootApplication(scanBasePackages = "com.demo") 12 | public class RedisApplication { 13 | public static void main(String[] args) { 14 | SpringApplication.run(RedisApplication.class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /study-redis/src/main/java/com/demo/domain/Message.java: -------------------------------------------------------------------------------- 1 | package com.demo.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | 8 | import java.io.Serializable; 9 | import java.util.Date; 10 | 11 | /** 12 | * User: lanxinghua 13 | * Date: 2019/11/4 15:34 14 | * Desc: 消息载体 15 | */ 16 | @Setter 17 | @Getter 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class Message implements Serializable { 21 | private String msgId; 22 | private String topic; 23 | private String tag; 24 | private String key; 25 | private Date storeTime; 26 | private String msgBody; 27 | } 28 | -------------------------------------------------------------------------------- /study-redis/src/main/java/com/demo/p2p/Constant.java: -------------------------------------------------------------------------------- 1 | package com.demo.p2p; 2 | 3 | /** 4 | * User: lanxinghua 5 | * Date: 2019/11/4 15:33 6 | * Desc: 7 | */ 8 | public class Constant { 9 | 10 | public static final String redisKey = "redisqueue"; 11 | public static final int msgSize = 10000; 12 | } 13 | -------------------------------------------------------------------------------- /study-redis/src/main/java/com/demo/p2p/Consumer.java: -------------------------------------------------------------------------------- 1 | package com.demo.p2p; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.demo.domain.Message; 5 | import com.demo.redis.RedisService; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.annotation.Resource; 9 | 10 | /** 11 | * User: lanxinghua 12 | * Date: 2019/11/4 15:32 13 | * Desc: 消费者 14 | */ 15 | @Component 16 | public class Consumer { 17 | @Resource 18 | private RedisService redisService; 19 | 20 | // 1万消息,消息队列的消费者 21 | public void consumer(){ 22 | for (int i = 0; i < Constant.msgSize; i++) { 23 | String str = redisService.rpop(Constant.redisKey); 24 | Message message = JSON.parseObject(str, Message.class); 25 | if (message != null){ 26 | System.out.println("消费成功:msgId:" + message.getMsgId() + JSON.toJSONString(message)); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /study-redis/src/main/java/com/demo/p2p/Producer.java: -------------------------------------------------------------------------------- 1 | package com.demo.p2p; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.demo.domain.Message; 5 | import com.demo.redis.RedisService; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.annotation.Resource; 9 | import java.util.Date; 10 | 11 | /** 12 | * User: lanxinghua 13 | * Date: 2019/11/4 15:32 14 | * Desc: 发布者 15 | */ 16 | @Component 17 | public class Producer { 18 | @Resource 19 | private RedisService redisService; 20 | 21 | // 1万消息,消息队列的生产者 22 | public void producer(){ 23 | for (int i = 1; i <= Constant.msgSize; i++) { 24 | String body = "{key:"+ i +"}"; 25 | Message message = new Message("" +i, "topic", "tag", "053a842", new Date(), body); 26 | redisService.lpush(Constant.redisKey, JSON.toJSONString(message)); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /study-redis/src/main/java/com/demo/pubsub/Constant.java: -------------------------------------------------------------------------------- 1 | package com.demo.pubsub; 2 | 3 | /** 4 | * User: lanxinghua 5 | * Date: 2019/11/4 15:33 6 | * Desc: 7 | */ 8 | public class Constant { 9 | 10 | public static final String topic = "CHANNEL"; 11 | public static final String redisKey = "redisqueue"; 12 | public static final int msgSize = 10000; 13 | } 14 | -------------------------------------------------------------------------------- /study-redis/src/main/java/com/demo/pubsub/Consumer.java: -------------------------------------------------------------------------------- 1 | package com.demo.pubsub; 2 | 3 | import com.demo.redis.RedisService; 4 | import org.springframework.stereotype.Component; 5 | 6 | import javax.annotation.Resource; 7 | 8 | /** 9 | * User: lanxinghua 10 | * Date: 2019/11/4 15:32 11 | * Desc: 消费者 12 | */ 13 | @Component("pubsubConsumer") 14 | public class Consumer { 15 | @Resource 16 | private RedisService redisService; 17 | 18 | public void subscribe(){ 19 | redisService.subscribe(new RedisMsgPubSubListener(), Constant.topic); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /study-redis/src/main/java/com/demo/pubsub/Producer.java: -------------------------------------------------------------------------------- 1 | package com.demo.pubsub; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.demo.domain.Message; 5 | import com.demo.redis.RedisService; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.annotation.Resource; 9 | import java.util.Date; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | /** 13 | * User: lanxinghua 14 | * Date: 2019/11/4 15:32 15 | * Desc: 生产者 16 | */ 17 | @Component("pubsubProducer") 18 | public class Producer { 19 | @Resource 20 | private RedisService redisService; 21 | 22 | public void producer(){ 23 | for (int i = 1; i <= 100; i++) { 24 | String body = "{key:"+ i +"}"; 25 | Message message = new Message("" +i, Constant.topic, "tag", "053a842", new Date(), body); 26 | redisService.publish(Constant.topic, JSON.toJSONString(message)); 27 | System.out.println("发布消息: msgId:" + message.getMsgId() + " msg:" + message.getMsgBody()); 28 | try { 29 | TimeUnit.SECONDS.sleep(1); 30 | }catch (Exception e){ 31 | e.printStackTrace(); 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /study-redis/src/main/java/com/demo/redis/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.demo.redis; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | @ConfigurationProperties(prefix="redis") 8 | public class RedisConfig { 9 | private String host; 10 | private int port; 11 | private int timeout;//秒 12 | private String password; 13 | private int poolMaxTotal; 14 | private int poolMaxIdle; 15 | private int poolMaxWait;//秒 16 | public String getHost() { 17 | return host; 18 | } 19 | public void setHost(String host) { 20 | this.host = host; 21 | } 22 | public int getPort() { 23 | return port; 24 | } 25 | public void setPort(int port) { 26 | this.port = port; 27 | } 28 | public int getTimeout() { 29 | return timeout; 30 | } 31 | public void setTimeout(int timeout) { 32 | this.timeout = timeout; 33 | } 34 | public String getPassword() { 35 | return password; 36 | } 37 | public void setPassword(String password) { 38 | this.password = password; 39 | } 40 | public int getPoolMaxTotal() { 41 | return poolMaxTotal; 42 | } 43 | public void setPoolMaxTotal(int poolMaxTotal) { 44 | this.poolMaxTotal = poolMaxTotal; 45 | } 46 | public int getPoolMaxIdle() { 47 | return poolMaxIdle; 48 | } 49 | public void setPoolMaxIdle(int poolMaxIdle) { 50 | this.poolMaxIdle = poolMaxIdle; 51 | } 52 | public int getPoolMaxWait() { 53 | return poolMaxWait; 54 | } 55 | public void setPoolMaxWait(int poolMaxWait) { 56 | this.poolMaxWait = poolMaxWait; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /study-redis/src/main/java/com/demo/redis/RedisPoolFactory.java: -------------------------------------------------------------------------------- 1 | package com.demo.redis; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.stereotype.Service; 6 | import redis.clients.jedis.JedisPool; 7 | import redis.clients.jedis.JedisPoolConfig; 8 | 9 | @Service 10 | public class RedisPoolFactory { 11 | 12 | @Autowired 13 | RedisConfig redisConfig; 14 | 15 | @Bean 16 | public JedisPool JedisPoolFactory() { 17 | JedisPoolConfig poolConfig = new JedisPoolConfig(); 18 | poolConfig.setMaxIdle(redisConfig.getPoolMaxIdle()); 19 | poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal()); 20 | poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait() * 1000); 21 | JedisPool jp = new JedisPool(poolConfig, redisConfig.getHost(), redisConfig.getPort(), 22 | redisConfig.getTimeout()*1000, redisConfig.getPassword(), 11); 23 | return jp; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /study-redis/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #redis 2 | redis.host=10.1.22.99 3 | redis.port=7091 4 | #redis.timeout=3 5 | #redis.password= 6 | redis.timeout=10 7 | 8 | #最大活动对象数 9 | redis.poolMaxTotal=1000 10 | # redis连接池最大的idle(空闲状态)连接个数 11 | redis.poolMaxIdle=500 12 | # jedis池没有对象返回时,最大等待时间 13 | redis.poolMaxWait=500 14 | -------------------------------------------------------------------------------- /study-redis/src/test/java/RedisPubTest.java: -------------------------------------------------------------------------------- 1 | import com.demo.RedisApplication; 2 | import com.demo.pubsub.Producer; 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 7 | 8 | import javax.annotation.Resource; 9 | 10 | /** 11 | * User: lanxinghua 12 | * Date: 2019/11/4 16:36 13 | * Desc: redis发布订阅测试-发布 14 | * {"key":"053a842","msgBody":"{key:57}","msgId":"57","storeTime":1572857690022,"tag":"tag","topic":"CHANNEL"} 15 | */ 16 | @RunWith(SpringJUnit4ClassRunner.class) 17 | @SpringBootTest(classes = RedisApplication.class) 18 | public class RedisPubTest { 19 | @Resource 20 | private Producer pubsubProducer; 21 | 22 | @Test 23 | public void publish(){ 24 | pubsubProducer.producer(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /study-redis/src/test/java/RedisQueueTest.java: -------------------------------------------------------------------------------- 1 | import com.demo.RedisApplication; 2 | import com.demo.p2p.Consumer; 3 | import com.demo.p2p.Producer; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 8 | 9 | import javax.annotation.Resource; 10 | 11 | /** 12 | * User: lanxinghua 13 | * Date: 2019/11/4 11:47 14 | * Desc: redis实现消息队列 15 | * 消息队列的先进先出(FIFO)的特点结合Redis的list中的push和pop操作进行封装 16 | */ 17 | @RunWith(SpringJUnit4ClassRunner.class) 18 | @SpringBootTest(classes = RedisApplication.class) 19 | public class RedisQueueTest { 20 | @Resource 21 | private Producer producer; 22 | @Resource 23 | private Consumer consumer; 24 | 25 | @Test 26 | public void test(){ 27 | push(); 28 | System.out.println("1万条消息生产完成....."); 29 | pop(); 30 | System.out.println("1万条消息消费完成....."); 31 | } 32 | 33 | // 1万消息,消息队列的生产者 34 | private void push(){ 35 | producer.producer(); 36 | } 37 | 38 | // 1万消息,消息队列的消费者 39 | private void pop(){ 40 | consumer.consumer(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /study-redis/src/test/java/RedisSubTest.java: -------------------------------------------------------------------------------- 1 | import com.demo.RedisApplication; 2 | import com.demo.pubsub.Consumer; 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 7 | 8 | import javax.annotation.Resource; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | /** 12 | * User: lanxinghua 13 | * Date: 2019/11/4 16:36 14 | * Desc: redis发布订阅测试-订阅 15 | */ 16 | @RunWith(SpringJUnit4ClassRunner.class) 17 | @SpringBootTest(classes = RedisApplication.class) 18 | public class RedisSubTest { 19 | @Resource 20 | private Consumer pubsubConsumer; 21 | 22 | @Test 23 | public void subscribe() throws Exception{ 24 | pubsubConsumer.subscribe(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/TranscationApplication.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | 8 | /** 9 | * User: lanxinghua 10 | * Date: 2019/10/19 13:52 11 | * Desc: 12 | */ 13 | @SpringBootApplication(scanBasePackages = {"com.demo"}) 14 | @MapperScan("com.demo.mapper") 15 | public class TranscationApplication { 16 | public static void main(String[] args) { 17 | SpringApplication.run(TranscationApplication.class); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/entity/Log.java: -------------------------------------------------------------------------------- 1 | package com.demo.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | public class Log implements Serializable { 6 | private String id; 7 | 8 | private String name; 9 | 10 | private Short isValid; 11 | 12 | private static final long serialVersionUID = 1L; 13 | 14 | public String getId() { 15 | return id; 16 | } 17 | 18 | public void setId(String id) { 19 | this.id = id == null ? null : id.trim(); 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name == null ? null : name.trim(); 28 | } 29 | 30 | public Short getIsValid() { 31 | return isValid; 32 | } 33 | 34 | public void setIsValid(Short isValid) { 35 | this.isValid = isValid; 36 | } 37 | } -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.demo.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | public class User implements Serializable { 6 | private String id; 7 | 8 | private String name; 9 | 10 | private Short isValid; 11 | 12 | private static final long serialVersionUID = 1L; 13 | 14 | public String getId() { 15 | return id; 16 | } 17 | 18 | public void setId(String id) { 19 | this.id = id == null ? null : id.trim(); 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name == null ? null : name.trim(); 28 | } 29 | 30 | public Short getIsValid() { 31 | return isValid; 32 | } 33 | 34 | public void setIsValid(Short isValid) { 35 | this.isValid = isValid; 36 | } 37 | } -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/mapper/LogMapper.java: -------------------------------------------------------------------------------- 1 | package com.demo.mapper; 2 | 3 | import com.demo.entity.Log; 4 | 5 | public interface LogMapper { 6 | int deleteByPrimaryKey(String id); 7 | 8 | int insert(Log record); 9 | 10 | int insertSelective(Log record); 11 | 12 | Log selectByPrimaryKey(String id); 13 | 14 | int updateByPrimaryKeySelective(Log record); 15 | 16 | int updateByPrimaryKey(Log record); 17 | } -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.demo.mapper; 2 | 3 | import com.demo.entity.User; 4 | 5 | public interface UserMapper { 6 | int deleteByPrimaryKey(String id); 7 | 8 | int insert(User record); 9 | 10 | int insertSelective(User record); 11 | 12 | User selectByPrimaryKey(String id); 13 | 14 | int updateByPrimaryKeySelective(User record); 15 | 16 | int updateByPrimaryKey(User record); 17 | } -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/redis/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.demo.redis; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | @ConfigurationProperties(prefix="redis") 8 | public class RedisConfig { 9 | private String host; 10 | private int port; 11 | private int timeout;//秒 12 | private String password; 13 | private int poolMaxTotal; 14 | private int poolMaxIdle; 15 | private int poolMaxWait;//秒 16 | public String getHost() { 17 | return host; 18 | } 19 | public void setHost(String host) { 20 | this.host = host; 21 | } 22 | public int getPort() { 23 | return port; 24 | } 25 | public void setPort(int port) { 26 | this.port = port; 27 | } 28 | public int getTimeout() { 29 | return timeout; 30 | } 31 | public void setTimeout(int timeout) { 32 | this.timeout = timeout; 33 | } 34 | public String getPassword() { 35 | return password; 36 | } 37 | public void setPassword(String password) { 38 | this.password = password; 39 | } 40 | public int getPoolMaxTotal() { 41 | return poolMaxTotal; 42 | } 43 | public void setPoolMaxTotal(int poolMaxTotal) { 44 | this.poolMaxTotal = poolMaxTotal; 45 | } 46 | public int getPoolMaxIdle() { 47 | return poolMaxIdle; 48 | } 49 | public void setPoolMaxIdle(int poolMaxIdle) { 50 | this.poolMaxIdle = poolMaxIdle; 51 | } 52 | public int getPoolMaxWait() { 53 | return poolMaxWait; 54 | } 55 | public void setPoolMaxWait(int poolMaxWait) { 56 | this.poolMaxWait = poolMaxWait; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/redis/RedisPoolFactory.java: -------------------------------------------------------------------------------- 1 | package com.demo.redis; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.stereotype.Service; 6 | import redis.clients.jedis.JedisPool; 7 | import redis.clients.jedis.JedisPoolConfig; 8 | 9 | @Service 10 | public class RedisPoolFactory { 11 | 12 | @Autowired 13 | RedisConfig redisConfig; 14 | 15 | @Bean 16 | public JedisPool JedisPoolFactory() { 17 | JedisPoolConfig poolConfig = new JedisPoolConfig(); 18 | poolConfig.setMaxIdle(redisConfig.getPoolMaxIdle()); 19 | poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal()); 20 | poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait() * 1000); 21 | JedisPool jp = new JedisPool(poolConfig, redisConfig.getHost(), redisConfig.getPort(), 22 | redisConfig.getTimeout()*1000, redisConfig.getPassword(), 11); 23 | return jp; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/service/ILogService.java: -------------------------------------------------------------------------------- 1 | package com.demo.service; 2 | 3 | import com.demo.entity.Log; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/10/19 14:48 8 | * Desc: 9 | */ 10 | public interface ILogService { 11 | int deleteByPrimaryKey(String id); 12 | 13 | int insert(Log record); 14 | 15 | int insertSelective(Log record); 16 | 17 | Log selectByPrimaryKey(String id); 18 | 19 | int updateByPrimaryKeySelective(Log record); 20 | 21 | int updateByPrimaryKey(Log record); 22 | } 23 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/service/IUserService.java: -------------------------------------------------------------------------------- 1 | package com.demo.service; 2 | 3 | import com.demo.entity.User; 4 | 5 | /** 6 | * User: lanxinghua 7 | * Date: 2019/10/19 14:24 8 | * Desc: 9 | */ 10 | public interface IUserService { 11 | public void addRequired(User user); 12 | public void addRequiredException(User user); 13 | public void addRequiredNew(User user); 14 | public void addRequiredNewException(User user); 15 | } 16 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/service/impl/LogService.java: -------------------------------------------------------------------------------- 1 | package com.demo.service.impl; 2 | 3 | import com.demo.entity.Log; 4 | import com.demo.mapper.LogMapper; 5 | import com.demo.service.ILogService; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.annotation.Resource; 9 | 10 | /** 11 | * User: lanxinghua 12 | * Date: 2019/10/19 14:48 13 | * Desc: 14 | */ 15 | @Service 16 | public class LogService implements ILogService { 17 | @Resource 18 | private LogMapper logMapper; 19 | 20 | public int deleteByPrimaryKey(String id) { 21 | return logMapper.deleteByPrimaryKey(id); 22 | } 23 | 24 | public int insert(Log record) { 25 | return logMapper.insert(record); 26 | } 27 | 28 | public int insertSelective(Log record) { 29 | return logMapper.insertSelective(record); 30 | } 31 | 32 | public Log selectByPrimaryKey(String id) { 33 | return logMapper.selectByPrimaryKey(id); 34 | } 35 | 36 | public int updateByPrimaryKeySelective(Log record) { 37 | return logMapper.updateByPrimaryKeySelective(record); 38 | } 39 | 40 | public int updateByPrimaryKey(Log record) { 41 | return logMapper.updateByPrimaryKey(record); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/service/impl/UserService.java: -------------------------------------------------------------------------------- 1 | package com.demo.service.impl; 2 | 3 | import com.demo.entity.User; 4 | import com.demo.mapper.UserMapper; 5 | import com.demo.service.IUserService; 6 | import org.springframework.stereotype.Service; 7 | import org.springframework.transaction.annotation.Propagation; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | import javax.annotation.Resource; 11 | 12 | /** 13 | * User: lanxinghua 14 | * Date: 2019/10/19 14:24 15 | * Desc: 16 | */ 17 | @Service 18 | public class UserService implements IUserService { 19 | @Resource 20 | private UserMapper userMapper; 21 | 22 | @Transactional(propagation = Propagation.REQUIRED) 23 | public void addRequired(User user) { 24 | userMapper.insert(user); 25 | } 26 | 27 | @Transactional(propagation = Propagation.REQUIRED) 28 | public void addRequiredException(User user) { 29 | int i = 10/0; 30 | userMapper.insert(user); 31 | } 32 | 33 | @Transactional(propagation = Propagation.REQUIRES_NEW) 34 | public void addRequiredNew(User user) { 35 | userMapper.insert(user); 36 | } 37 | 38 | @Transactional(propagation = Propagation.REQUIRES_NEW) 39 | public void addRequiredNewException(User user) { 40 | int i = 10/0; 41 | userMapper.insert(user); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/txtest/ITxService.java: -------------------------------------------------------------------------------- 1 | package com.demo.txtest; 2 | 3 | /** 4 | * User: lanxinghua 5 | * Date: 2019/10/19 15:03 6 | * Desc: 7 | */ 8 | public interface ITxService { 9 | /** 10 | * 总结:1和2,外围无事务,哪个方法报错,哪个回滚 11 | * 1、外围无事务有异常,里面有两个添加方法,可以添加成功 12 | */ 13 | void notxException_required_required(); 14 | /** 15 | * 2、外围无事务无异常,里面有两个添加方法,其中一个事务方法内部异常,导致回滚 16 | */ 17 | void notx_required_requiredException(); 18 | 19 | 20 | /** 21 | * 3、外围有事务且有异常,里面有两个添加方法,不论外围有异常,还是其他方法有异常,全都回滚 22 | */ 23 | void txException_required_required(); 24 | 25 | /** 26 | * 4、外围有事务且有异常,不回滚 27 | */ 28 | void txException_requiredNew_requiredNew(); 29 | 30 | /** 31 | * 5、外围有事务且有异常,里面有两个添加方法,requiredNewException的进行回滚 32 | */ 33 | void txException_requiredNew_requiredNewException(); 34 | 35 | /** 36 | * 6、外围有事务且有异常,里面有两个添加方法,外部插入成功,内部回滚 37 | */ 38 | void txException_required_requiredExceptionTry(); 39 | 40 | /** 41 | * 7.在一个类里面:没事务方法A调有事务方法B,B的事务会被忽略调 42 | */ 43 | void notx_notxMethod_txMethodException(); 44 | 45 | void notx_notxMethod_txMethodException1(); 46 | } 47 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/txtest/TxRedisService.java: -------------------------------------------------------------------------------- 1 | package com.demo.txtest; 2 | 3 | import com.demo.util.LockEnum; 4 | import com.demo.util.LockUtil; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | import org.springframework.transaction.annotation.Transactional; 8 | 9 | import java.util.concurrent.TimeUnit; 10 | import java.util.function.Function; 11 | 12 | /** 13 | * User: lanxinghua 14 | * Date: 2019/10/23 17:11 15 | * Desc: java中锁与@Transactional同时使用导致锁失效的问题 16 | * 问题分析:由于spring aop会在update方法之前开启事务,之后再加锁,当锁住代码后执行完后再提交事务:finally方法运行完,删除key后,事务还未提交。导致其他 17 | * 线程进行代码块,读取的数据不是最新的。 18 | * 19 | * 解决办法:在update之前就加上锁(还没开启事务前就加上锁) 20 | */ 21 | @Service 22 | public class TxRedisService { 23 | @Autowired 24 | private LockUtil lockUtil; 25 | @Autowired 26 | private TxRedisService txRedisService; 27 | 28 | @Transactional 29 | public void update(String key){ 30 | boolean lock = lockUtil.lock(LockEnum.TEST, key, false); 31 | if (!lock){ 32 | throw new RuntimeException("当前人数过多,请稍后再试!"); 33 | } 34 | try { 35 | System.out.println("处理业务逻辑: " + key); 36 | }catch (Exception e){ 37 | e.printStackTrace(); 38 | }finally { 39 | lockUtil.unlock(LockEnum.TEST, key); 40 | } 41 | } 42 | 43 | /** 44 | * 将锁粒度范围扩大 45 | * @param key 46 | */ 47 | public void updatev1(String key){ 48 | boolean lock = lockUtil.lock(LockEnum.TEST, key, false); 49 | if (!lock){ 50 | throw new RuntimeException("当前人数过多,请稍后再试!"); 51 | } 52 | try { 53 | txRedisService.innerUpdate(key); 54 | }catch (Exception e){ 55 | e.printStackTrace(); 56 | }finally { 57 | lockUtil.unlock(LockEnum.TEST, key); 58 | } 59 | } 60 | 61 | @Transactional 62 | public void innerUpdate(String key){ 63 | System.out.println("处理业务逻辑: " + key); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/util/JedisClient.java: -------------------------------------------------------------------------------- 1 | package com.demo.util; 2 | 3 | public interface JedisClient { 4 | 5 | String set(String key, String value); 6 | String get(String key); 7 | Boolean exists(String key); 8 | Long expire(String key, int seconds); 9 | Long ttl(String key); 10 | Long incr(String key); 11 | Long hset(String key, String field, String value); 12 | String hget(String key, String field); 13 | Long hdel(String key, String... field); 14 | } 15 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/util/JedisClientPool.java: -------------------------------------------------------------------------------- 1 | package com.demo.util; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | 5 | import redis.clients.jedis.Jedis; 6 | import redis.clients.jedis.JedisPool; 7 | 8 | public class JedisClientPool implements JedisClient { 9 | 10 | @Autowired 11 | private JedisPool jedisPool; 12 | 13 | @Override 14 | public String set(String key, String value) { 15 | Jedis jedis = jedisPool.getResource(); 16 | String result = jedis.set(key, value); 17 | jedis.close(); 18 | return result; 19 | } 20 | 21 | @Override 22 | public String get(String key) { 23 | Jedis jedis = jedisPool.getResource(); 24 | String result = jedis.get(key); 25 | jedis.close(); 26 | return result; 27 | } 28 | 29 | @Override 30 | public Boolean exists(String key) { 31 | Jedis jedis = jedisPool.getResource(); 32 | Boolean result = jedis.exists(key); 33 | jedis.close(); 34 | return result; 35 | } 36 | 37 | @Override 38 | public Long expire(String key, int seconds) { 39 | Jedis jedis = jedisPool.getResource(); 40 | Long result = jedis.expire(key, seconds); 41 | jedis.close(); 42 | return result; 43 | } 44 | 45 | @Override 46 | public Long ttl(String key) { 47 | Jedis jedis = jedisPool.getResource(); 48 | Long result = jedis.ttl(key); 49 | jedis.close(); 50 | return result; 51 | } 52 | 53 | @Override 54 | public Long incr(String key) { 55 | Jedis jedis = jedisPool.getResource(); 56 | Long result = jedis.incr(key); 57 | jedis.close(); 58 | return result; 59 | } 60 | 61 | @Override 62 | public Long hset(String key, String field, String value) { 63 | Jedis jedis = jedisPool.getResource(); 64 | Long result = jedis.hset(key, field, value); 65 | jedis.close(); 66 | return result; 67 | } 68 | 69 | @Override 70 | public String hget(String key, String field) { 71 | Jedis jedis = jedisPool.getResource(); 72 | String result = jedis.hget(key, field); 73 | jedis.close(); 74 | return result; 75 | } 76 | 77 | @Override 78 | public Long hdel(String key, String... field) { 79 | Jedis jedis = jedisPool.getResource(); 80 | Long result = jedis.hdel(key, field); 81 | jedis.close(); 82 | return result; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/util/LockEnum.java: -------------------------------------------------------------------------------- 1 | package com.demo.util; 2 | 3 | /** 4 | * User: lanxinghua 5 | * Date: 2019/10/23 11:50 6 | * Desc: 7 | */ 8 | public enum LockEnum { 9 | TEST("testkey:", 60, "请稍后在操作!") 10 | ; 11 | 12 | /** 13 | * 操作key 14 | */ 15 | private String key; 16 | /** 17 | * 操作过期时间 18 | */ 19 | private int expiredTime; 20 | /** 21 | * 异常消息 22 | */ 23 | private String errMsg; 24 | 25 | LockEnum(String key, int expiredTime, String errMsg) { 26 | this.key = key; 27 | this.expiredTime = expiredTime; 28 | this.errMsg = errMsg; 29 | } 30 | 31 | public String getKey() { 32 | return key; 33 | } 34 | 35 | public void setKey(String key) { 36 | this.key = key; 37 | } 38 | 39 | public int getExpiredTime() { 40 | return expiredTime; 41 | } 42 | 43 | public void setExpiredTime(int expiredTime) { 44 | this.expiredTime = expiredTime; 45 | } 46 | 47 | public String getErrMsg() { 48 | return errMsg; 49 | } 50 | 51 | public void setErrMsg(String errMsg) { 52 | this.errMsg = errMsg; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /study-transcation/src/main/java/com/demo/util/LockUtil.java: -------------------------------------------------------------------------------- 1 | package com.demo.util; 2 | 3 | import com.demo.redis.RedisService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.stereotype.Component; 6 | 7 | import javax.annotation.Resource; 8 | 9 | /** 10 | * User: lanxinghua 11 | * Date: 2019/10/23 11:49 12 | * Desc: 13 | */ 14 | @Component 15 | public class LockUtil { 16 | @Autowired 17 | private RedisService redisService; 18 | 19 | public boolean lock(LockEnum lockOp, String key, boolean needCheck) { 20 | boolean result = lock(lockOp, key); 21 | if (needCheck && !result) { 22 | throw new RuntimeException(lockOp.getErrMsg()); 23 | } 24 | return result; 25 | } 26 | 27 | public boolean lock(LockEnum lockOp, String key, boolean wait, long waitTime, int pollingCount) { 28 | boolean result; 29 | int index = 0; 30 | while ((result = lock(lockOp, key) && wait && pollingCount > index)) { 31 | try { 32 | Thread.sleep(waitTime); 33 | } catch (InterruptedException e) { 34 | //ignore 35 | } finally { 36 | index++; 37 | } 38 | } 39 | return result; 40 | } 41 | 42 | public boolean unlock(LockEnum lockOp, String key) { 43 | String lockKey = getLockKey(lockOp, key); 44 | return redisService.del(lockKey) > 0; 45 | } 46 | 47 | private boolean lock(LockEnum lockOp, String key) { 48 | String lockKey = getLockKey(lockOp, key); 49 | return redisService.setnx(lockKey, "value", lockOp.getExpiredTime()); 50 | } 51 | 52 | private String getLockKey(LockEnum lockOp, String key) { 53 | return lockOp.getKey() + key; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /study-transcation/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #redis 2 | redis.host=10.1.22.99 3 | redis.port=7091 4 | #redis.timeout=3 5 | #redis.password= 6 | #redis.poolMaxTotal=10 7 | #redis.poolMaxIdle=10 8 | #redis.poolMaxWait=3 9 | redis.timeout=10 10 | redis.poolMaxTotal=1000 11 | redis.poolMaxIdle=500 12 | redis.poolMaxWait=500 13 | -------------------------------------------------------------------------------- /study-transcation/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | 4 | spring: 5 | datasource: 6 | name: test 7 | url: jdbc:mysql://10.1.6.10:3306/lxh 8 | username: twodfire 9 | password: 123456 10 | driver-class-name: com.mysql.jdbc.Driver 11 | 12 | mybatis: 13 | mapper-locations: classpath:mapper/*.xml #注意:一定要对应mapper映射xml文件的所在路径 14 | type-aliases-package: com.demo.entity # 注意:对应实体类的路径 15 | 16 | -------------------------------------------------------------------------------- /study-transcation/src/main/resources/generatorConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
48 |
49 |
50 | -------------------------------------------------------------------------------- /study-transcation/src/test/java/com/demo/RedisAndTxTest.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import com.demo.txtest.TxRedisService; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 9 | 10 | import java.util.concurrent.ExecutorService; 11 | import java.util.concurrent.Executors; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | /** 15 | * User: lanxinghua 16 | * Date: 2019/10/24 09:49 17 | * Desc: 18 | */ 19 | @RunWith(SpringJUnit4ClassRunner.class) 20 | @SpringBootTest(classes = TranscationApplication.class) 21 | public class RedisAndTxTest { 22 | @Autowired 23 | private TxRedisService txRedisService; 24 | private ExecutorService executorService = Executors.newCachedThreadPool(); 25 | 26 | /** 27 | * java中锁和事务同时使用,导致锁失效问题测试 28 | */ 29 | @Test 30 | public void test01(){ 31 | for (int i = 0; i < 10; i++) { 32 | executorService.execute(new Runnable() { 33 | @Override 34 | public void run() { 35 | txRedisService.update("lxh"); 36 | } 37 | }); 38 | } 39 | sleep(); 40 | } 41 | 42 | /** 43 | * java中锁和事务同时使用,锁粒度扩大 44 | */ 45 | @Test 46 | public void test02(){ 47 | for (int i = 0; i < 10; i++) { 48 | executorService.execute(new Runnable() { 49 | @Override 50 | public void run() { 51 | txRedisService.updatev1("lxh"); 52 | } 53 | }); 54 | } 55 | sleep(); 56 | } 57 | 58 | private void sleep(){ 59 | try { 60 | TimeUnit.SECONDS.sleep(1); 61 | }catch (Exception e){ 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /study-transcation/src/test/java/com/demo/TxTest.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | import com.demo.txtest.ITxService; 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 7 | 8 | import javax.annotation.Resource; 9 | 10 | /** 11 | * User: lanxinghua 12 | * Date: 2019/10/19 14:30 13 | * Desc: 事务测试 14 | */ 15 | @RunWith(SpringJUnit4ClassRunner.class) 16 | @SpringBootTest(classes = TranscationApplication.class) 17 | public class TxTest { 18 | @Resource 19 | private ITxService txService; 20 | 21 | @Test 22 | public void test01(){ 23 | txService.notxException_required_required(); 24 | } 25 | 26 | @Test 27 | public void test02(){ 28 | txService.notx_required_requiredException(); 29 | } 30 | 31 | @Test 32 | public void test03(){ 33 | txService.txException_required_required(); 34 | } 35 | 36 | @Test 37 | public void test04(){ 38 | txService.txException_requiredNew_requiredNew(); 39 | } 40 | 41 | @Test 42 | public void test05(){ 43 | txService.txException_requiredNew_requiredNewException(); 44 | } 45 | 46 | 47 | @Test 48 | public void test06(){ 49 | txService.txException_required_requiredExceptionTry(); 50 | } 51 | 52 | @Test 53 | public void test07(){ 54 | txService.notx_notxMethod_txMethodException(); 55 | } 56 | @Test 57 | public void test08(){ 58 | txService.notx_notxMethod_txMethodException1(); 59 | } 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /study-uml/README.MD: -------------------------------------------------------------------------------- 1 | ## 创建时序图 2 | -------------------------------------------------------------------------------- /study-uml/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | study-uml 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /study-uml/src/uml/alipay1.puml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @startuml 5 | 支付宝小程序 -> weixin as "weixin-meal": 1.授权 /malllogin/alipay/{code} 6 | 7 | weixin -> oauth as "oauth-api": : 2.授权 8 | oauth -> 支付宝开发平台 : 3.获取支付宝用户信息 9 | 支付宝开发平台 -> oauth : 4.返回用户信息 10 | oauth -> weixin : 4. 返回结果 11 | weixin -> 支付宝小程序 : 5. 返回结果 12 | @enduml 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /study-uml/src/uml/alipay2.puml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @startuml 5 | 支付宝小程序 -> weixin as "weixin-meal": 1.上传用户信息 /ma/up_user_info/alipay/mallperson/{code} 6 | weixin -> oauth as "oauth-api": : 2.上传用户信息 7 | oauth -> 支付宝开发平台 : 3.获取支付宝用户信息 8 | 支付宝开发平台 -> oauth : 4.返回用户信息 9 | oauth -> weixin : 4. 返回结果 10 | weixin -> 支付宝小程序 : 5. 返回结果 11 | @enduml 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /study-uml/src/uml/alipay3.puml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @startuml 5 | 二维码 -> weixin as "weixin-meal": 1.商户扫码授权 6 | weixin -> oauth as "oauth-api": : 2.扫码授权 7 | oauth -> third as "third-internal-soa" : 3.保存授权信息 8 | third -> oauth : 4.返回结果 9 | oauth -> weixin : 5. 返回结果 10 | weixin -> 二维码 : 6. 返回结果 11 | @enduml 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /study-uml/src/uml/alipay4.puml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @startuml 5 | 运营后台 -> dmall as "dmall-boss-api": 1.操作小程序 6 | note right 7 | 1.模板管理(微信/支付宝) 8 | 2.小程序授权(微信/支付宝) 9 | 3.小程序管理(升级) 10 | end note 11 | dmall -> wechat as "wechat-soa": : 2.操作小程序 12 | wechat -> third as "third-internal-soa" : 3.操作小程序 13 | third -> wechat : 4.返回结果 14 | wechat -> dmall : 5. 返回结果 15 | dmall -> 运营后台 : 6. 返回结果 16 | @enduml 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /study-uml/src/uml/lxh1.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | 掌柜审核H5 -> mis as "mis-center": 1.网关接口 3 | mis -> mis : 2.判断时间临界点 4 | alt time < 临界点时间 5 | mis -> matrix as "matrix-soa": 3.获取系统数据 6 | note right 7 | 实收额 8 | 订单数量 9 | end note 10 | matrix -> mis : 4.返回结果 11 | else time >= 临界点时间 12 | mis -> matrix as "matrix-soa": 5.获取系统数据 13 | note right 14 | 营业额 15 | 订单数量 16 | end note 17 | matrix -> mis : 6.返回结果 18 | end 19 | mis -> 掌柜审核H5 : 7. 返回结果 20 | @enduml 21 | -------------------------------------------------------------------------------- /study-uml/src/uml/lxh2.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | 掌柜 -> api as "boss-api": 1.获取首页数据 3 | api -> api : 2.判断商圈是否使用ERP 4 | alt 不使用ERP 5 | api -> api: 6 | note right 7 | 功能不变 8 | end note 9 | else 使用ERP 10 | api -> mis as "mis-center-soa": 3.获取数据 11 | alt 获取店铺列表 12 | mis -> shop as "shop-soa" : 4.获取店铺列表(时间范围+mallEntityId) 13 | shop -> mis: 5.返回店铺列表(进行缓存) 14 | mis -> bps as "bps-soa": 6.获取用户可管理的楼层业态 15 | bps -> mis:7.返回权限列表 16 | mis -> mis: 8.获取过滤后的店铺(进行缓存) 17 | note right 18 | 1.用户可管理的 19 | 2.不是统收台店铺 20 | end note 21 | end 22 | mis -> data as "data-lake-soa": 9.获取数据【H+1,T+1】参数:(时间范围,门店列表) 23 | data -> mis: 10.返回数据 24 | mis -> api: 11.返回数据 25 | end 26 | api -> 掌柜 : 12. 返回结果 27 | @enduml 28 | -------------------------------------------------------------------------------- /study-uml/src/uml/test1.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | "APP(商场)" -> 网关: 审核数据 4 | 网关 -> "mis-center-soa": 审核 5 | "mis-center-soa" -> "matrix-soa": 取系统数据 6 | "matrix-soa" --> "mis-center-soa": return 7 | "mis-center-soa" --> "mis-center-soa": 系统数据和上报数据比较,取高值 8 | "mis-center-soa" --> "网关": 审核成功 9 | 网关 --> "APP(商场)": return 10 | title: 销售数据审核 11 | 12 | @enduml 13 | -------------------------------------------------------------------------------- /study-uml/src/uml/test2.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | H5 -> wx as "weixin": 1./v1/coupon/fetch 3 | wx -> wx : 2.是否是商圈 4 | alt 不是商圈 5 | wx -> cs as "xx-soa": 3.领取优惠券 6 | cs -> mc as "xx-center": 4.领取优惠券 7 | mc -> cs : 5.返回结果 8 | cs -> wx : 6. 返回结果 9 | else 是商圈 10 | wx -> ap as "xx-platform": 7.是否为商圈会员 11 | ap -> ap: 8.判断是否为商圈会员 12 | alt 不是会员 13 | ap -> wx : 9.返回结果,需要先加入会员 14 | else 是会员 15 | wx -> cs as "xx-soa": 10.领取优惠券 16 | cs -> mc as "xx-center": 11.领取优惠券 17 | mc -> cs : 12.返回结果 18 | cs -> wx : 13. 返回结果 19 | end 20 | end 21 | wx -> H5 : 14. 返回结果 22 | @enduml 23 | -------------------------------------------------------------------------------- /study-uml/src/uml/test3.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | Alice->Bob : hello 3 | note left: 添加注释 4 | 5 | Bob->Alice : ok 6 | note right: 添加注释 7 | 8 | Bob->Bob : I am thinking 9 | note left 10 | a note 11 | can also be defined 12 | on several lines 13 | end note 14 | @enduml 15 | -------------------------------------------------------------------------------- /study-zk/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sourcecode 7 | com.demo 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | study-zk 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /study-zk/src/main/java/com/demo/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: lanxinghua 3 | * Date: 2019/11/13 14:09 4 | * Desc: 5 | */ 6 | package com.demo; 7 | --------------------------------------------------------------------------------