├── .gitignore ├── Drools └── drools-quickstart │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── drools │ │ │ └── quickstart │ │ │ ├── entity │ │ │ ├── ComparisonOperatorEntity.java │ │ │ ├── Order.java │ │ │ └── Student.java │ │ │ └── service │ │ │ └── UserService.java │ └── resources │ │ ├── META-INF │ │ └── kmodule.xml │ │ └── rules │ │ ├── activationgroup.drl │ │ ├── agendagroup.drl │ │ ├── bookDiscount.drl │ │ ├── comparisonOperator.drl │ │ ├── function.drl │ │ ├── global.drl │ │ ├── noloop.drl │ │ ├── query.drl │ │ ├── student.drl │ │ └── timer.drl │ └── test │ └── java │ └── com │ └── drools │ └── quickstart │ └── DroolsTest.java ├── FX ├── AOP基础.png ├── AOP基础.xmind ├── IOC基础-AC.png ├── IOC基础-ApplicationContext.xmind ├── IOC基础-BF.png ├── IOC基础-BeanFactory.xmind ├── IOC基础-工作机制.png ├── IOC基础-工作机制.xmind └── IOC基础.xmind ├── GOF ├── gof-example │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ ├── MavenWrapperDownloader.java │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── ipipman │ │ │ │ └── gof │ │ │ │ └── example │ │ │ │ ├── GofExampleApplication.java │ │ │ │ ├── chain │ │ │ │ ├── AuthInfo.java │ │ │ │ ├── AuthLink.java │ │ │ │ ├── AuthService.java │ │ │ │ ├── ChainTest.java │ │ │ │ ├── Level1AuthLink.java │ │ │ │ ├── Level2AuthLink.java │ │ │ │ └── Level3AuthLink.java │ │ │ │ ├── foobar │ │ │ │ └── Foobar.java │ │ │ │ ├── proxy │ │ │ │ ├── GOF-Proxy代理模式.md │ │ │ │ ├── IPersonService.java │ │ │ │ ├── InvocationProxy.java │ │ │ │ └── PersonServiceImpl.java │ │ │ │ ├── singleton │ │ │ │ ├── GOF-Singleton单例模式.md │ │ │ │ ├── IdGenerator1.java │ │ │ │ ├── IdGenerator2.java │ │ │ │ ├── IdGenerator3.java │ │ │ │ ├── IdGenerator4.java │ │ │ │ └── IdGenerator5.java │ │ │ │ └── solution │ │ │ │ └── ArraySearchSolution.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── ipipman │ │ └── gof │ │ └── example │ │ └── GofExampleApplicationTests.java ├── 设计模式一.png ├── 设计模式一.xmind ├── 设计模式三.png ├── 设计模式三.xmind ├── 设计模式二.png └── 设计模式二.xmind ├── JAVA8 ├── JAVA8.xmind └── Java8.png ├── JUC ├── 信号量.xmind ├── 信号量(并发控制).png ├── 多线程基础.png ├── 多线程基础.xmind ├── 并发包JUC.xmind ├── 并发集合类.png ├── 并发集合类.xmind ├── 线程安全.png ├── 线程安全.xmind ├── 线程池.png └── 线程池.xmind ├── JVM ├── GC垃圾回收.png ├── GC垃圾回收.xmind ├── JDK命令行工具.png ├── JDK命令行工具.xmind ├── JVM内存模型.png ├── JVM内存模型.xmind ├── JVM启动参数.png ├── JVM启动参数.xmind ├── JVM类加载器.png ├── JVM类加载器.xmind ├── Java字节码技术.png └── Java字节码技术.xmind ├── MQ ├── JMQ异步处理消息的实现.png ├── JMQ异步处理消息的实现.xmind ├── Kafka中Consumer源码分析.png ├── Kafka中Consumer源码分析.xmind ├── Kafka协调者Zookeeper.png ├── Kafka协调者Zookeeper.xmind ├── Kafka和RocketMQ消息复制.png ├── Kafka和RocketMQ消息复制.xmind ├── Kafka缓存策略.png ├── Kafka缓存策略.xmind ├── Kafka高性能IO.png ├── Kafka高性能IO.xmind ├── Mysql:Perf-Test.png ├── RocketMQ与Kafka事务.png ├── RocketMQ与Kafka事务.xmind ├── RocketMQ协调者NameServer.png ├── RocketMQ协调者NameServer.xmind ├── RocketMQ的Producer源码分析.png ├── RocketMQ的Producer源码分析.xmind ├── 事务消息实现分布式事务概述.png ├── 事务消息实现分布式事务概述.xmind ├── 正确的使用锁保护共享数据.png ├── 正确的使用锁保护共享数据.xmind ├── 消息队列数据丢失解决方案.png ├── 消息队列的基本概念.png └── 消息队列的基本概念.xmind ├── Mysql ├── Mysql中的日志.png ├── Mysql中的锁.png ├── Mysql中的锁.xmind ├── Mysql主从.png ├── Mysql主从.xmind ├── Mysql事务.png ├── Mysql事务.xmind ├── Mysql优化.png ├── Mysql优化方案.xmind ├── Mysql架构设计.png ├── Mysql架构设计.xmind ├── Mysql的日志.xmind ├── Mysql索引设计.png ├── Mysql索引设计.xmind ├── 关系型数据库.png └── 关系型数据库.xmind ├── NIO ├── Netty核心内幕.png ├── Netty线程模型.png ├── Netty线程模型.xmind ├── Nett核心内幕.xmind ├── 常用IO模型.png └── 常用IO模型.xmind ├── README.md ├── XT ├── Base柔性事务.png ├── Base柔性事务.xmind ├── XA分布式事务.png └── XA分布式事务.xmind └── 技术架构 ├── (1)架构的标准定义.md ├── (2)画出优秀的架构图.md ├── (3)面向复杂度架构设计.md └── (4)如何做好架构设计.md /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | logs/ 4 | .idea 5 | 1.txt 6 | ======= 7 | *.iws 8 | *.iml 9 | *.ipr 10 | 11 | ### NetBeans ### 12 | /nbproject/private/ 13 | /nbbuild/ 14 | /dist/` 15 | /nbdist/ 16 | /.nb-gradle/ 17 | build/ 18 | 19 | ### VS Code ### 20 | .vscode/ 21 | /logs/ 22 | batch.txt 23 | 24 | ### project .gitignore ### 25 | # jd es 测试文件 26 | upload/* 27 | rebel.xml 28 | #generatorConfigLinux.xml 29 | 30 | # mac 31 | .DS_Store 32 | 33 | /out 34 | 35 | /Week_05/spring-boot-2.1.x -------------------------------------------------------------------------------- /Drools/drools-quickstart/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | drools-quickstart 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 8 14 | 8 15 | 16 | 17 | 18 | 19 | org.drools 20 | drools-compiler 21 | 7.10.0.Final 22 | 23 | 24 | 25 | junit 26 | junit 27 | 4.12 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/java/com/drools/quickstart/entity/ComparisonOperatorEntity.java: -------------------------------------------------------------------------------- 1 | package com.drools.quickstart.entity; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 实体类 7 | * 用于测试比较操作符 8 | */ 9 | public class ComparisonOperatorEntity { 10 | private String names; 11 | private List list; 12 | 13 | public String getNames() { 14 | return names; 15 | } 16 | 17 | public void setNames(String names) { 18 | this.names = names; 19 | } 20 | 21 | public List getList() { 22 | return list; 23 | } 24 | 25 | public void setList(List list) { 26 | this.list = list; 27 | } 28 | } -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/java/com/drools/quickstart/entity/Order.java: -------------------------------------------------------------------------------- 1 | package com.drools.quickstart.entity; 2 | 3 | 4 | /** 5 | * 订单 6 | * @date 2021-06-22 12:18 7 | * @author huangyan110110114 8 | */ 9 | public class Order { 10 | 11 | /** 12 | * 订单原始价格,即优惠前价格 13 | */ 14 | private Double originalPrice; 15 | 16 | /** 17 | * 订单真实价格,即优惠后价格 18 | */ 19 | private Double realPrice; 20 | 21 | public String toString() { 22 | return "Order{" + 23 | "originalPrice=" + originalPrice + 24 | ", realPrice=" + realPrice + 25 | '}'; 26 | } 27 | 28 | public Double getOriginalPrice() { 29 | return originalPrice; 30 | } 31 | 32 | public void setOriginalPrice(Double originalPrice) { 33 | this.originalPrice = originalPrice; 34 | } 35 | 36 | public Double getRealPrice() { 37 | return realPrice; 38 | } 39 | 40 | public void setRealPrice(Double realPrice) { 41 | this.realPrice = realPrice; 42 | } 43 | } -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/java/com/drools/quickstart/entity/Student.java: -------------------------------------------------------------------------------- 1 | package com.drools.quickstart.entity; 2 | 3 | /** 4 | * 学生 5 | */ 6 | public class Student { 7 | private int id; 8 | private String name; 9 | private int age; 10 | 11 | public int getId() { 12 | return id; 13 | } 14 | 15 | public void setId(int id) { 16 | this.id = id; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public void setName(String name) { 24 | this.name = name; 25 | } 26 | 27 | public int getAge() { 28 | return age; 29 | } 30 | 31 | public void setAge(int age) { 32 | this.age = age; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return "Student{" + 38 | "id=" + id + 39 | ", name='" + name + '\'' + 40 | ", age=" + age + 41 | '}'; 42 | } 43 | } -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/java/com/drools/quickstart/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.drools.quickstart.service; 2 | 3 | public class UserService { 4 | public void save(){ 5 | System.out.println("UserService.save()..."); 6 | } 7 | } -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/resources/META-INF/kmodule.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/resources/rules/activationgroup.drl: -------------------------------------------------------------------------------- 1 | package testactivationgroup 2 | /* 3 | 此规则文件用于测试activation-group属性 4 | */ 5 | 6 | 7 | rule "rule_activationgroup_1" 8 | /** 9 | activation-group属性是指激活分组,取值为String类型。具有相同分组名称的规则只能有一个规则被触发。 10 | */ 11 | activation-group "mygroup" 12 | when 13 | then 14 | System.out.println("规则rule_activationgroup_1触发"); 15 | end 16 | 17 | rule "rule_activationgroup_2" 18 | /** 19 | activation-group属性是指激活分组,取值为String类型。具有相同分组名称的规则只能有一个规则被触发。 20 | */ 21 | activation-group "mygroup" 22 | when 23 | then 24 | System.out.println("规则rule_activationgroup_2触发"); 25 | end -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/resources/rules/agendagroup.drl: -------------------------------------------------------------------------------- 1 | package testagendagroup 2 | /* 3 | 此规则文件用于测试agenda-group属性 4 | */ 5 | rule "rule_agendagroup_1" 6 | /** 7 | agenda-group属性为议程分组,属于另一种可控的规则执行方式。 8 | 用户可以通过设置agenda-group来控制规则的执行,只有获取焦点的组中的规则才会被触发。 9 | */ 10 | agenda-group "myagendagroup_1" 11 | when 12 | then 13 | System.out.println("规则rule_agendagroup_1触发"); 14 | end 15 | 16 | rule "rule_agendagroup_2" 17 | /** 18 | agenda-group属性为议程分组,属于另一种可控的规则执行方式。 19 | 用户可以通过设置agenda-group来控制规则的执行,只有获取焦点的组中的规则才会被触发。 20 | */ 21 | agenda-group "myagendagroup_1" 22 | when 23 | then 24 | System.out.println("规则rule_agendagroup_2触发"); 25 | end 26 | 27 | //======================================================== 28 | rule "rule_agendagroup_3" 29 | /** 30 | agenda-group属性为议程分组,属于另一种可控的规则执行方式。 31 | 用户可以通过设置agenda-group来控制规则的执行,只有获取焦点的组中的规则才会被触发。 32 | */ 33 | agenda-group "myagendagroup_2" 34 | /** 35 | 自动获取焦点 36 | */ 37 | auto-focus true 38 | when 39 | then 40 | System.out.println("规则rule_agendagroup_3触发"); 41 | end 42 | 43 | rule "rule_agendagroup_4" 44 | /** 45 | agenda-group属性为议程分组,属于另一种可控的规则执行方式。 46 | 用户可以通过设置agenda-group来控制规则的执行,只有获取焦点的组中的规则才会被触发。 47 | */ 48 | agenda-group "myagendagroup_2" 49 | /** 50 | 自动获取焦点 51 | */ 52 | auto-focus true 53 | when 54 | then 55 | System.out.println("规则rule_agendagroup_4触发"); 56 | end -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/resources/rules/bookDiscount.drl: -------------------------------------------------------------------------------- 1 | //图书优惠规则 2 | package book.discount 3 | import com.drools.quickstart.entity.Order; 4 | import org.drools.core.util.StringUtils; 5 | 6 | //规则一:所购图书总价在100元以下的没有优惠 7 | rule "book_discount_1" 8 | when 9 | $order:Order(originalPrice < 100) 10 | then 11 | $order.setRealPrice($order.getOriginalPrice()); 12 | System.out.println("成功匹配到规则一:所购图书总价在100元以下的没有优惠"); 13 | end 14 | 15 | //规则二:所购图书总价在100到200元的优惠20元 16 | rule "book_discount_2" 17 | when 18 | $order:Order(originalPrice < 200 && originalPrice >= 100) 19 | then 20 | $order.setRealPrice($order.getOriginalPrice() - 20); 21 | System.out.println("成功匹配到规则二:所购图书总价在100到200元的优惠20元"); 22 | end 23 | 24 | //规则三:所购图书总价在200到300元的优惠50元 25 | rule "book_discount_3" 26 | when 27 | $order:Order(originalPrice <= 300 && originalPrice >= 200) 28 | then 29 | $order.setRealPrice($order.getOriginalPrice() - 50); 30 | System.out.println("成功匹配到规则三:所购图书总价在200到300元的优惠50元"); 31 | end 32 | 33 | //规则四:所购图书总价在300元以上的优惠100元 34 | rule "book_discount_4" 35 | when 36 | $order:Order(originalPrice >= 300) 37 | then 38 | $order.setRealPrice($order.getOriginalPrice() - 100); 39 | System.out.println("成功匹配到规则四:所购图书总价在300元以上的优惠100元"); 40 | end -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/resources/rules/comparisonOperator.drl: -------------------------------------------------------------------------------- 1 | package comparisonOperator 2 | import com.drools.quickstart.entity.ComparisonOperatorEntity; 3 | 4 | /* 5 | 当前规则文件用于测试Drools提供的比较操作符 6 | */ 7 | 8 | //测试比较操作符contains 9 | rule "rule_comparison_contains" 10 | when 11 | ComparisonOperatorEntity(names contains "张三") 12 | ComparisonOperatorEntity(list contains names) 13 | then 14 | System.out.println("规则rule_comparison_contains触发"); 15 | end 16 | 17 | //测试比较操作符not contains 18 | rule "rule_comparison_notContains" 19 | when 20 | ComparisonOperatorEntity(names not contains "张三") 21 | and 22 | ComparisonOperatorEntity(list not contains names) 23 | then 24 | System.out.println("规则rule_comparison_notContains触发"); 25 | end 26 | 27 | //测试比较操作符memberOf 28 | rule "rule_comparison_memberOf" 29 | when 30 | ComparisonOperatorEntity(names memberOf list) 31 | then 32 | System.out.println("规则rule_comparison_memberOf触发"); 33 | end 34 | 35 | //测试比较操作符not memberOf 36 | rule "rule_comparison_notMemberOf" 37 | when 38 | ComparisonOperatorEntity(names not memberOf list) 39 | then 40 | System.out.println("规则rule_comparison_notMemberOf触发"); 41 | end 42 | 43 | //测试比较操作符matches 44 | rule "rule_comparison_matches" 45 | when 46 | ComparisonOperatorEntity(names matches "张.*") 47 | then 48 | System.out.println("规则rule_comparison_matches触发"); 49 | end 50 | 51 | //测试比较操作符not matches 52 | rule "rule_comparison_notMatches" 53 | when 54 | ComparisonOperatorEntity(names not matches "张.*") 55 | then 56 | System.out.println("规则rule_comparison_notMatches触发"); 57 | end -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/resources/rules/function.drl: -------------------------------------------------------------------------------- 1 | package testfunction 2 | import com.drools.quickstart.entity.Student; 3 | 4 | 5 | /* 6 | 此规则文件用于测试function函数 7 | function关键字用于在规则文件中定义函数,就相当于java类中的方法一样。 8 | 可以在规则体中调用定义的函数。使用函数的好处是可以将业务逻辑集中放置在一个地方,根据需要可以对函数进行修改。 9 | */ 10 | 11 | //定义一个函数 12 | function String sayHello(String name){ 13 | return "hello " + name; 14 | } 15 | 16 | rule "rule_function_1" 17 | when 18 | $student:Student(name != null) 19 | then 20 | //调用上面定义的函数 21 | String ret = sayHello($student.getName()); 22 | System.out.println(ret); 23 | end -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/resources/rules/global.drl: -------------------------------------------------------------------------------- 1 | package testglobal 2 | 3 | /* 4 | 此规则文件用于测试global全局变量 5 | */ 6 | 7 | global java.lang.Integer count //定义一个包装类型的全局变量 8 | global com.drools.quickstart.service.UserService userService //定义一个JavaBean类型的全局变量 9 | global java.util.List gList //定义一个集合类型的全局变量 10 | 11 | rule "rule_global_1" 12 | when 13 | then 14 | System.out.println("触发:rule_global_1"); 15 | count += 10; //全局变量计算,只对当前规则有效,其他规则不受影响 16 | userService.save();//调用全局变量的方法 17 | gList.add("itcast");//向集合类型的全局变量中添加元素,Java代码和所有规则都受影响 18 | gList.add("itheima"); 19 | System.out.println("count=" + count); 20 | System.out.println("gList.size=" + gList.size()); 21 | System.out.println("gList=" + gList); 22 | end 23 | 24 | rule "rule_global_2" 25 | when 26 | then 27 | System.out.println("触发:rule_global_2"); 28 | userService.save(); 29 | System.out.println("count=" + count); 30 | System.out.println("gList.size=" + gList.size()); 31 | System.out.println("gList=" + gList); 32 | end -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/resources/rules/noloop.drl: -------------------------------------------------------------------------------- 1 | package testnoloop 2 | import com.drools.quickstart.entity.Student; 3 | 4 | /* 5 | 此规则文件用于测试no-loop属性 6 | */ 7 | 8 | rule "rule_noloop" 9 | /** 10 | no-loop属性用于防止死循环,当规则通过update之类的函数修改了Fact对象时,可能使当前规则再次被激活从而导致死循环 11 | */ 12 | no-loop true 13 | when 14 | $student:Student(age == 25) 15 | then 16 | update($student);//注意此处执行update会导致当前规则重新被激活 17 | System.out.println("规则rule_noloop触发"); 18 | end -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/resources/rules/query.drl: -------------------------------------------------------------------------------- 1 | package testquery 2 | import com.drools.quickstart.entity.Student; 3 | 4 | /* 5 | 此规则文件用于测试query查询 6 | */ 7 | 8 | //query查询提供了一种查询working memory中符合约束条件的Fact对象的简单方法。 9 | //它仅包含规则文件中的LHS部分,不用指定“when”和“then”部分并且以end结束。 10 | 11 | //不带参数的查询 12 | //当前query用于查询Working Memory中age>10的Student对象 13 | query "query_1" 14 | $student:Student(age > 10) 15 | end 16 | 17 | //带有参数的查询 18 | //当前query用于查询Working Memory中age>10同时name需要和传递的参数name相同的Student对象 19 | query "query_2"(String sname) 20 | $student:Student(age > 20 && name == sname) 21 | end -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/resources/rules/student.drl: -------------------------------------------------------------------------------- 1 | package student 2 | import com.drools.quickstart.entity.Student; 3 | 4 | /* 5 | 当前规则文件用于测试Drools提供的内置方法 6 | */ 7 | 8 | // retract删除工作区中的fact 9 | rule "rule_student_age等于10岁时删除数据" 10 | /* 11 | salience:设置当前规则的执行优先级,数值越大越优先执行,默认值为0. 12 | 因为当前规则的匹配条件和下面规则的匹配条件相同,为了保证先执行当前规则,需要设置优先级 13 | */ 14 | salience 100 15 | //指定当前规则不可用,当前规则无论是否匹配成功都不会执行 16 | enabled true 17 | //dialect属性用于指定当前规则使用的语言类型,取值为java和mvel,默认值为java。 18 | dialect "java" 19 | when 20 | $s:Student(age == 10) 21 | then 22 | retract($s);//retract方法的作用是删除工作内存中的数据,并让相关的规则重新匹配。 23 | System.out.println("规则rule_student_age等于10岁时删除数据触发"); 24 | end 25 | 26 | // 当前规则测试insert内置方法 27 | rule "rule_student_age等于10岁" 28 | when 29 | $s:Student(age == 10) 30 | then 31 | Student student = new Student(); 32 | student.setAge(5); 33 | insert(student);//插入数据,导致相关的规则会重新匹配 34 | System.out.println("规则rule_student_age等于10岁触发"); 35 | end 36 | 37 | // 当前规则测试update内置方法 38 | rule "rule_student_age小于10岁" 39 | when 40 | $s:Student(age < 10) 41 | then 42 | $s.setAge(15); 43 | update($s); 44 | System.out.println("规则rule_student_age小于10岁触发"); 45 | end 46 | 47 | // 当前规则测试update内置方法 48 | rule "rule_student_age小于20岁同时大于10岁" 49 | when 50 | $s:Student(age < 20 && age > 10) 51 | then 52 | $s.setAge(25); 53 | update($s); 54 | System.out.println("规则rule_student_age小于20岁同时大于10岁触发"); 55 | end 56 | 57 | // 当前规则测试update内置方法 58 | rule "rule_student_age大于20岁" 59 | when 60 | $s:Student(age > 20) 61 | then 62 | System.out.println("规则rule_student_age大于20岁触发"); 63 | end -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/main/resources/rules/timer.drl: -------------------------------------------------------------------------------- 1 | package testtimer 2 | import java.text.SimpleDateFormat 3 | import java.util.Date 4 | /* 5 | 此规则文件用于测试timer属性 6 | */ 7 | 8 | rule "rule_timer_1" 9 | timer (5s 2s) //含义:5秒后触发,然后每隔2秒触发一次 10 | when 11 | then 12 | System.out.println("规则rule_timer_1触发,触发时间为:" + 13 | new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); 14 | end 15 | 16 | rule "rule_timer_2" 17 | timer (cron:0/1 * * * * ?) //含义:每隔1秒触发一次 18 | when 19 | then 20 | System.out.println("规则rule_timer_2触发,触发时间为:" + 21 | new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); 22 | end -------------------------------------------------------------------------------- /Drools/drools-quickstart/src/test/java/com/drools/quickstart/DroolsTest.java: -------------------------------------------------------------------------------- 1 | package com.drools.quickstart; 2 | 3 | import com.drools.quickstart.entity.ComparisonOperatorEntity; 4 | import com.drools.quickstart.entity.Order; 5 | import com.drools.quickstart.entity.Student; 6 | import com.drools.quickstart.service.UserService; 7 | import org.drools.core.base.RuleNameEqualsAgendaFilter; 8 | import org.junit.Test; 9 | import org.kie.api.KieServices; 10 | import org.kie.api.runtime.KieContainer; 11 | import org.kie.api.runtime.KieSession; 12 | import org.kie.api.runtime.rule.QueryResults; 13 | import org.kie.api.runtime.rule.QueryResultsRow; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | /** 19 | * Created by ipipman on 2021/6/22. 20 | * 21 | * @version V1.0 22 | * @Package com.drools 23 | * @Description: (用一句话描述该文件做什么) 24 | * @date 2021/6/22 1:51 下午 25 | */ 26 | public class DroolsTest { 27 | 28 | @Test 29 | public void test1() { 30 | 31 | KieServices kieServices = KieServices.Factory.get(); 32 | // 获得Kie容器对象 33 | KieContainer kieContainer = kieServices.newKieClasspathContainer(); 34 | // 从Kie容器对象中获取会话对象,会话对象,用于和规则引擎交互 35 | KieSession session = kieContainer.newKieSession(); 36 | 37 | // 构造一个对象(Fact对象,事实对象) 38 | Order order = new Order(); 39 | order.setOriginalPrice(210D); 40 | 41 | // 将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配 42 | session.insert(order); 43 | 44 | //激活规则引擎,如果规则匹配成功则执行规则 45 | session.fireAllRules(); 46 | 47 | //关闭会话 48 | session.dispose(); 49 | } 50 | 51 | //测试比较操作符 52 | @Test 53 | public void test3() { 54 | KieServices kieServices = KieServices.Factory.get(); 55 | KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); 56 | KieSession kieSession = kieClasspathContainer.newKieSession(); 57 | 58 | ComparisonOperatorEntity comparisonOperatorEntity = new ComparisonOperatorEntity(); 59 | comparisonOperatorEntity.setNames("张三"); 60 | List list = new ArrayList(); 61 | list.add("张三"); 62 | list.add("李四"); 63 | comparisonOperatorEntity.setList(list); 64 | 65 | //将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则 66 | kieSession.insert(comparisonOperatorEntity); 67 | 68 | kieSession.fireAllRules(); 69 | kieSession.dispose(); 70 | } 71 | 72 | //执行指定规则 73 | @Test 74 | public void test4() { 75 | KieServices kieServices = KieServices.Factory.get(); 76 | KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); 77 | KieSession kieSession = kieClasspathContainer.newKieSession(); 78 | 79 | ComparisonOperatorEntity comparisonOperatorEntity = new ComparisonOperatorEntity(); 80 | comparisonOperatorEntity.setNames("张三"); 81 | List list = new ArrayList(); 82 | list.add("张三"); 83 | list.add("李四"); 84 | comparisonOperatorEntity.setList(list); 85 | kieSession.insert(comparisonOperatorEntity); 86 | 87 | //通过规则过滤器实现只执行指定规则 88 | kieSession.fireAllRules(new RuleNameEqualsAgendaFilter("rule_comparison_memberOf")); 89 | 90 | kieSession.dispose(); 91 | } 92 | 93 | //测试RHS部分的update方法 94 | @Test 95 | public void test5() { 96 | KieServices kieServices = KieServices.Factory.get(); 97 | KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); 98 | KieSession kieSession = kieClasspathContainer.newKieSession(); 99 | 100 | Student student = new Student(); 101 | student.setAge(5); 102 | 103 | //将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则 104 | kieSession.insert(student); 105 | 106 | kieSession.fireAllRules(); 107 | kieSession.dispose(); 108 | } 109 | 110 | //测试RHS部分的insert方法 111 | @Test 112 | public void test6() { 113 | KieServices kieServices = KieServices.Factory.get(); 114 | KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); 115 | KieSession kieSession = kieClasspathContainer.newKieSession(); 116 | 117 | Student student = new Student(); 118 | student.setAge(10); 119 | 120 | //将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则 121 | kieSession.insert(student); 122 | 123 | kieSession.fireAllRules(); 124 | kieSession.dispose(); 125 | } 126 | 127 | //测试rule属性no-loop 128 | @Test 129 | public void test7() { 130 | KieServices kieServices = KieServices.Factory.get(); 131 | KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); 132 | KieSession kieSession = kieClasspathContainer.newKieSession(); 133 | 134 | Student student = new Student(); 135 | student.setAge(25); 136 | 137 | //将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则 138 | kieSession.insert(student); 139 | 140 | kieSession.fireAllRules(); 141 | kieSession.dispose(); 142 | } 143 | 144 | //测试rule属性activation-group,激活分组 145 | @Test 146 | public void test8() { 147 | //activation-group属性是指激活分组,取值为String类型。具有相同分组名称的规则只能有一个规则被触发。 148 | KieServices kieServices = KieServices.Factory.get(); 149 | KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); 150 | KieSession kieSession = kieClasspathContainer.newKieSession(); 151 | kieSession.fireAllRules(); 152 | kieSession.dispose(); 153 | } 154 | 155 | //测试rule属性agenda-group,议程分组,需要指定焦点 156 | @Test 157 | public void test9() { 158 | KieServices kieServices = KieServices.Factory.get(); 159 | KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); 160 | KieSession kieSession = kieClasspathContainer.newKieSession(); 161 | 162 | //设置焦点,对应agenda-group分组中的规则才可能被触发 163 | kieSession.getAgenda().getAgendaGroup("myagendagroup_1").setFocus(); 164 | 165 | kieSession.fireAllRules(); 166 | kieSession.dispose(); 167 | } 168 | 169 | //测试rule属性timer,定时器 170 | @Test 171 | public void test10() throws Exception { 172 | KieServices kieServices = KieServices.Factory.get(); 173 | KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); 174 | final KieSession kieSession = kieClasspathContainer.newKieSession(); 175 | 176 | new Thread(new Runnable() { 177 | public void run() { 178 | //启动规则引擎进行规则匹配,直到调用halt方法才结束规则引擎 179 | kieSession.fireUntilHalt(); 180 | } 181 | }).start(); 182 | 183 | Thread.sleep(10000); 184 | //结束规则引擎 185 | kieSession.halt(); 186 | kieSession.dispose(); 187 | } 188 | 189 | //测试rule高级语法global 190 | @Test 191 | public void test11() { 192 | KieServices kieServices = KieServices.Factory.get(); 193 | KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); 194 | KieSession kieSession = kieClasspathContainer.newKieSession(); 195 | 196 | //设置全局变量,名称和类型必须和规则文件中定义的全局变量名称对应 197 | kieSession.setGlobal("userService", new UserService()); 198 | kieSession.setGlobal("count", 5); 199 | List list = new ArrayList(); //size为0 200 | list.add("ipman"); 201 | kieSession.setGlobal("gList", list); 202 | 203 | kieSession.fireAllRules(); 204 | kieSession.dispose(); 205 | 206 | //因为在规则中为全局变量添加了两个元素,所以现在的size为2 207 | System.out.println(list.size()); 208 | } 209 | 210 | //query查询提供了一种查询working memory中符合约束条件的Fact对象的简单方法。 211 | // 它仅包含规则文件中的LHS部分,不用指定“when”和“then”部分并且以end结束。 212 | @Test 213 | public void test12() { 214 | KieServices kieServices = KieServices.Factory.get(); 215 | KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); 216 | KieSession kieSession = kieClasspathContainer.newKieSession(); 217 | 218 | Student student1 = new Student(); 219 | student1.setName("张三"); 220 | student1.setAge(12); 221 | 222 | Student student2 = new Student(); 223 | student2.setName("李四"); 224 | student2.setAge(8); 225 | 226 | Student student3 = new Student(); 227 | student3.setName("王五"); 228 | student3.setAge(22); 229 | 230 | //将对象插入Working Memory中 231 | kieSession.insert(student1); 232 | kieSession.insert(student2); 233 | kieSession.insert(student3); 234 | 235 | //调用规则文件中的查询 236 | QueryResults results1 = kieSession.getQueryResults("query_1"); 237 | int size = results1.size(); 238 | System.out.println("size=" + size); 239 | for (QueryResultsRow row : results1) { 240 | Student student = (Student) row.get("$student"); 241 | System.out.println(student); 242 | } 243 | 244 | //调用规则文件中的查询 245 | QueryResults results2 = kieSession.getQueryResults("query_2", "王五"); 246 | size = results2.size(); 247 | System.out.println("size=" + size); 248 | for (QueryResultsRow row : results2) { 249 | Student student = (Student) row.get("$student"); 250 | System.out.println(student); 251 | } 252 | //kieSession.fireAllRules(); 253 | kieSession.dispose(); 254 | } 255 | 256 | 257 | //function关键字用于在规则文件中定义函数,就相当于java类中的方法一样。可以在规则体中调用定义的函数。 258 | //使用函数的好处是可以将业务逻辑集中放置在一个地方,根据需要可以对函数进行修改。 259 | @Test 260 | public void test13() { 261 | KieServices kieServices = KieServices.Factory.get(); 262 | KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer(); 263 | KieSession kieSession = kieClasspathContainer.newKieSession(); 264 | 265 | Student student = new Student(); 266 | student.setName("小明"); 267 | 268 | kieSession.insert(student); 269 | 270 | //kieSession.fireAllRules(); 271 | kieSession.dispose(); 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /FX/AOP基础.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/FX/AOP基础.png -------------------------------------------------------------------------------- /FX/AOP基础.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/FX/AOP基础.xmind -------------------------------------------------------------------------------- /FX/IOC基础-AC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/FX/IOC基础-AC.png -------------------------------------------------------------------------------- /FX/IOC基础-ApplicationContext.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/FX/IOC基础-ApplicationContext.xmind -------------------------------------------------------------------------------- /FX/IOC基础-BF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/FX/IOC基础-BF.png -------------------------------------------------------------------------------- /FX/IOC基础-BeanFactory.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/FX/IOC基础-BeanFactory.xmind -------------------------------------------------------------------------------- /FX/IOC基础-工作机制.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/FX/IOC基础-工作机制.png -------------------------------------------------------------------------------- /FX/IOC基础-工作机制.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/FX/IOC基础-工作机制.xmind -------------------------------------------------------------------------------- /FX/IOC基础.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/FX/IOC基础.xmind -------------------------------------------------------------------------------- /GOF/gof-example/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /GOF/gof-example/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import java.net.*; 17 | import java.io.*; 18 | import java.nio.channels.*; 19 | import java.util.Properties; 20 | 21 | public class MavenWrapperDownloader { 22 | 23 | private static final String WRAPPER_VERSION = "0.5.6"; 24 | /** 25 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 26 | */ 27 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 28 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 29 | 30 | /** 31 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 32 | * use instead of the default one. 33 | */ 34 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 35 | ".mvn/wrapper/maven-wrapper.properties"; 36 | 37 | /** 38 | * Path where the maven-wrapper.jar will be saved to. 39 | */ 40 | private static final String MAVEN_WRAPPER_JAR_PATH = 41 | ".mvn/wrapper/maven-wrapper.jar"; 42 | 43 | /** 44 | * Name of the property which should be used to override the default download url for the wrapper. 45 | */ 46 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 47 | 48 | public static void main(String args[]) { 49 | System.out.println("- Downloader started"); 50 | File baseDirectory = new File(args[0]); 51 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 52 | 53 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 54 | // wrapperUrl parameter. 55 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 56 | String url = DEFAULT_DOWNLOAD_URL; 57 | if(mavenWrapperPropertyFile.exists()) { 58 | FileInputStream mavenWrapperPropertyFileInputStream = null; 59 | try { 60 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 61 | Properties mavenWrapperProperties = new Properties(); 62 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 63 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 64 | } catch (IOException e) { 65 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 66 | } finally { 67 | try { 68 | if(mavenWrapperPropertyFileInputStream != null) { 69 | mavenWrapperPropertyFileInputStream.close(); 70 | } 71 | } catch (IOException e) { 72 | // Ignore ... 73 | } 74 | } 75 | } 76 | System.out.println("- Downloading from: " + url); 77 | 78 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 79 | if(!outputFile.getParentFile().exists()) { 80 | if(!outputFile.getParentFile().mkdirs()) { 81 | System.out.println( 82 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 83 | } 84 | } 85 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 86 | try { 87 | downloadFileFromURL(url, outputFile); 88 | System.out.println("Done"); 89 | System.exit(0); 90 | } catch (Throwable e) { 91 | System.out.println("- Error downloading"); 92 | e.printStackTrace(); 93 | System.exit(1); 94 | } 95 | } 96 | 97 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 98 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 99 | String username = System.getenv("MVNW_USERNAME"); 100 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 101 | Authenticator.setDefault(new Authenticator() { 102 | @Override 103 | protected PasswordAuthentication getPasswordAuthentication() { 104 | return new PasswordAuthentication(username, password); 105 | } 106 | }); 107 | } 108 | URL website = new URL(urlString); 109 | ReadableByteChannel rbc; 110 | rbc = Channels.newChannel(website.openStream()); 111 | FileOutputStream fos = new FileOutputStream(destination); 112 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 113 | fos.close(); 114 | rbc.close(); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /GOF/gof-example/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/GOF/gof-example/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /GOF/gof-example/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /GOF/gof-example/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /GOF/gof-example/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /GOF/gof-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.4.4 9 | 10 | 11 | com.ipipman.gof.example 12 | gof-example 13 | 0.0.1-SNAPSHOT 14 | gof-example 15 | Demo project for Spring Boot 16 | 17 | 1.8 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-test 28 | test 29 | 30 | 31 | 32 | com.alibaba 33 | fastjson 34 | 1.2.70 35 | 36 | 37 | 38 | org.projectlombok 39 | lombok 40 | true 41 | 1.18.12 42 | provided 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-maven-plugin 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/GofExampleApplication.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class GofExampleApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(GofExampleApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/chain/AuthInfo.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.chain; 2 | 3 | /** 4 | * Created by ipipman on 2021/4/22. 5 | * 6 | * @version V1.0 7 | * @Package com.ipipman.gof.example.chain 8 | * @Description: (用一句话描述该文件做什么) 9 | * @date 2021/4/22 10:11 上午 10 | */ 11 | public class AuthInfo { 12 | 13 | private String code; 14 | private String info = ""; 15 | 16 | public AuthInfo(String code, String... infos) { 17 | this.code = code; 18 | for (String str : infos) { 19 | this.info = this.info.concat(str); 20 | } 21 | } 22 | 23 | public String getCode() { 24 | return code; 25 | } 26 | 27 | public void setCode(String code) { 28 | this.code = code; 29 | } 30 | 31 | public String getInfo() { 32 | return info; 33 | } 34 | 35 | public void setInfo(String info) { 36 | this.info = info; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/chain/AuthLink.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.chain; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | import java.util.Objects; 6 | 7 | /** 8 | * Created by ipipman on 2021/4/22. 9 | * 10 | * @version V1.0 11 | * @Package com.ipipman.gof.example.chain 12 | * @Description: (用一句话描述该文件做什么) 13 | * @date 2021/4/22 10:03 上午 14 | */ 15 | public abstract class AuthLink { 16 | 17 | // 时间格式化 18 | protected SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 19 | // 级别人员ID 20 | protected String levelUserId; 21 | // 级别人员姓名 22 | protected String levelUserName; 23 | // 下一个责任链 24 | private AuthLink next; 25 | 26 | // 构造方法 27 | public AuthLink(String levelUserId, String levelUserName) { 28 | this.levelUserId = levelUserId; 29 | this.levelUserName = levelUserName; 30 | } 31 | 32 | // 返回下一个责任链条 33 | public AuthLink next() { 34 | return this.next; 35 | } 36 | 37 | // 加入下一个责任链 38 | public AuthLink appendNext(AuthLink next) { 39 | this.next = next; 40 | return this; 41 | } 42 | 43 | // 审核 44 | public abstract AuthInfo doAuth(String uId, String orderId, Date authDate); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/chain/AuthService.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.chain; 2 | 3 | import java.util.Date; 4 | import java.util.Map; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | 7 | /** 8 | * Created by ipipman on 2021/4/22. 9 | * 10 | * @version V1.0 11 | * @Package com.ipipman.gof.example.chain 12 | * @Description: (用一句话描述该文件做什么) 13 | * @date 2021/4/22 10:18 上午 14 | */ 15 | public class AuthService { 16 | 17 | private static final Map authMap = new ConcurrentHashMap<>(); 18 | 19 | public static Date queryAuthInfo(String uId, String orderId) { 20 | return authMap.get(uId.concat(orderId)); 21 | } 22 | 23 | public static void auth(String uId, String orderId) { 24 | authMap.put(uId.concat(orderId), new Date()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/chain/ChainTest.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.chain; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.text.ParseException; 8 | import java.util.Date; 9 | import java.util.logging.Logger; 10 | 11 | /** 12 | * Created by ipipman on 2021/4/22. 13 | * 14 | * @version V1.0 15 | * @Package com.ipipman.gof.example.chain 16 | * @Description: (用一句话描述该文件做什么) 17 | * @date 2021/4/22 10:34 上午 18 | */ 19 | @Slf4j 20 | public class ChainTest { 21 | 22 | 23 | public static void main(String[] args) throws ParseException { 24 | AuthLink authLink = new Level3AuthLink("1000013", "王工") 25 | .appendNext(new Level2AuthLink("1000012", "张经理") 26 | .appendNext(new Level1AuthLink("1000011", "段总"))); 27 | 28 | log.info("测试结果:{}", JSON.toJSONString(authLink.doAuth("小傅哥", "1000998004813441", new Date()))); 29 | 30 | // 模拟三级负责人审批 31 | AuthService.auth("1000013", "1000998004813441"); 32 | log.info("测试结果:{}", "模拟三级负责人审批,王工"); 33 | log.info("测试结果:{}", JSON.toJSONString(authLink.doAuth("小傅哥", "1000998004813441", new Date()))); 34 | 35 | // 模拟二级负责人审批 36 | AuthService.auth("1000012", "1000998004813441"); 37 | log.info("测试结果:{}", "模拟二级负责人审批,张经理"); 38 | log.info("测试结果:{}", JSON.toJSONString(authLink.doAuth("小傅哥", "1000998004813441", new Date()))); 39 | 40 | // 模拟一级负责人审批 41 | AuthService.auth("1000011", "1000998004813441"); 42 | log.info("测试结果:{}", "模拟一级负责人审批,段总"); 43 | log.info("测试结果:{}", JSON.toJSONString(authLink.doAuth("小傅哥", "1000998004813441", new Date()))); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/chain/Level1AuthLink.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.chain; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Created by ipipman on 2021/4/22. 7 | * 8 | * @version V1.0 9 | * @Package com.ipipman.gof.example.chain 10 | * @Description: (用一句话描述该文件做什么) 11 | * @date 2021/4/22 10:15 上午 12 | */ 13 | public class Level1AuthLink extends AuthLink { 14 | 15 | // 初始化父类 16 | public Level1AuthLink(String levelUserId, String levelUserName) { 17 | super(levelUserId, levelUserName); 18 | } 19 | 20 | @Override 21 | public AuthInfo doAuth(String uId, String orderId, Date authDate) { 22 | Date date = AuthService.queryAuthInfo(levelUserId, orderId); 23 | if (date == null) { 24 | return new AuthInfo("0001", "单号:", orderId, " 状态:待一级审批负责人 ", levelUserName); 25 | } 26 | AuthLink next = super.next(); 27 | if (null == next) { 28 | return new AuthInfo("0000", "单号:", orderId, " 状态:一级审批完成负责人", " 时间:", sdf.format(date), " 审批人:", levelUserName); 29 | } 30 | return next.doAuth(uId, orderId, authDate); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/chain/Level2AuthLink.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.chain; 2 | 3 | import java.text.ParseException; 4 | import java.util.Date; 5 | 6 | /** 7 | * Created by ipipman on 2021/4/22. 8 | * 9 | * @version V1.0 10 | * @Package com.ipipman.gof.example.chain 11 | * @Description: (用一句话描述该文件做什么) 12 | * @date 2021/4/22 10:15 上午 13 | */ 14 | public class Level2AuthLink extends AuthLink { 15 | 16 | private final Date beginDate = sdf.parse("2020-06-11 00:00:00"); 17 | private final Date endDate = sdf.parse("2020-06-20 23:59:59"); 18 | 19 | // 初始化父类 20 | public Level2AuthLink(String levelUserId, String levelUserName) throws ParseException { 21 | super(levelUserId, levelUserName); 22 | } 23 | 24 | @Override 25 | public AuthInfo doAuth(String uId, String orderId, Date authDate) { 26 | Date date = AuthService.queryAuthInfo(levelUserId, orderId); 27 | if (date == null) { 28 | return new AuthInfo("0001", "单号:", orderId, " 状态:待二级审批负责人 ", levelUserName); 29 | } 30 | AuthLink next = super.next(); 31 | if (null == next) { 32 | return new AuthInfo("0000", "单号:", orderId, " 状态:二级审批完成负责人", " 时间:", sdf.format(date), " 审批人:", levelUserName); 33 | } 34 | // if (authDate.before(beginDate) || authDate.after(endDate)){ 35 | // return new AuthInfo("0000", "单号:", orderId, " 状态:二级审批完成负责人", " 时间:", sdf.format(date), " 审批人:", levelUserName); 36 | // } 37 | return next.doAuth(uId, orderId, authDate); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/chain/Level3AuthLink.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.chain; 2 | 3 | import java.text.ParseException; 4 | import java.util.Date; 5 | 6 | /** 7 | * Created by ipipman on 2021/4/22. 8 | * 9 | * @version V1.0 10 | * @Package com.ipipman.gof.example.chain 11 | * @Description: (用一句话描述该文件做什么) 12 | * @date 2021/4/22 10:15 上午 13 | */ 14 | public class Level3AuthLink extends AuthLink { 15 | 16 | private final Date beginDate = sdf.parse("2020-06-01 00:00:00"); 17 | private final Date endDate = sdf.parse("2020-06-25 23:59:59"); 18 | 19 | // 初始化父类 20 | public Level3AuthLink(String levelUserId, String levelUserName) throws ParseException { 21 | super(levelUserId, levelUserName); 22 | } 23 | 24 | @Override 25 | public AuthInfo doAuth(String uId, String orderId, Date authDate) { 26 | Date date = AuthService.queryAuthInfo(levelUserId, orderId); 27 | if (date == null) { 28 | return new AuthInfo("0001", "单号:", orderId, " 状态:待三级审批负责人 ", levelUserName); 29 | } 30 | AuthLink next = super.next(); 31 | if (null == next) { 32 | return new AuthInfo("0000", "单号:", orderId, " 状态:三级审批完成负责人", " 时间:", sdf.format(date), " 审批人:", levelUserName); 33 | } 34 | // if (authDate.before(beginDate) || authDate.after(endDate)){ 35 | // return new AuthInfo("0000", "单号:", orderId, " 状态:三级审批完成负责人", " 时间:", sdf.format(date), " 审批人:", levelUserName); 36 | // } 37 | return next.doAuth(uId, orderId, authDate); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/foobar/Foobar.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.foobar; 2 | 3 | import javafx.scene.SubScene; 4 | 5 | import java.util.concurrent.ExecutorService; 6 | import java.util.concurrent.Executors; 7 | import java.util.concurrent.Semaphore; 8 | 9 | /** 10 | * Created by ipipman on 2021/5/13. 11 | * 12 | * @version V1.0 13 | * @Package com.ipipman.gof.example.forbar 14 | * @Description: (用一句话描述该文件做什么) 15 | * @date 2021/5/13 6:44 下午 16 | */ 17 | public class Foobar { 18 | 19 | private final int n; 20 | 21 | private Semaphore foo = new Semaphore(1); 22 | private Semaphore bar = new Semaphore(0); 23 | 24 | Foobar(int n) { 25 | this.n = n; 26 | } 27 | 28 | public void printFoo(Runnable r) { 29 | for (int i = 0; i <= n; i++) { 30 | try { 31 | foo.acquire(); 32 | r.run(); 33 | bar.release(); 34 | } catch (InterruptedException e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | } 39 | 40 | public void printBar(Runnable r) { 41 | for (int i = 0; i <= n; i++) { 42 | try { 43 | bar.acquire(); 44 | r.run(); 45 | foo.release(); 46 | } catch (InterruptedException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | } 51 | 52 | public static void main(String[] args) throws InterruptedException { 53 | Foobar foobar = new Foobar(10); 54 | Thread t1 = new Thread(() -> { 55 | foobar.printFoo(new Runnable() { 56 | public void run() { 57 | System.out.print("foo"); 58 | } 59 | }); 60 | }); 61 | 62 | Thread t2 = new Thread(() -> { 63 | foobar.printBar(() -> { 64 | System.out.print("bar\n"); 65 | }); 66 | }); 67 | t1.start(); 68 | t2.start(); 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/proxy/GOF-Proxy代理模式.md: -------------------------------------------------------------------------------- 1 | ### Proxy 设计模式 2 | 3 | #### 什么是代理模式? 4 | 5 | **代理模式** (Proxy Design Pattern); 6 | 7 | 它在不改变原始类(或叫被代理类)代码的情况下,通过引入代理类给原始类附加功能; 8 | 9 | 10 | 11 | #### Java1.3 动态代理InvocationHandler 12 | 13 | ```java 14 | // Java 1.3 动态代理 15 | public class InvocationProxy implements InvocationHandler { 16 | 17 | private Object delegate; 18 | 19 | public Object bind(Object delegate) { 20 | this.delegate = delegate; 21 | ClassLoader classLoader = delegate.getClass().getClassLoader(); 22 | Class[] clazz = delegate.getClass().getInterfaces(); 23 | return Proxy.newProxyInstance(classLoader, clazz, this::invoke); 24 | } 25 | 26 | @Override 27 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 28 | Object result = null; 29 | try { 30 | System.out.println("InvocationHandler start ..."); 31 | result = method.invoke(delegate, args); 32 | System.out.println("InvocationHandler end ..."); 33 | } catch (Exception e) { 34 | e.printStackTrace(); 35 | } 36 | return result; 37 | } 38 | 39 | // TODO Testing ... 40 | public static void main(String[] args) { 41 | InvocationProxy invocationProxy = new InvocationProxy(); 42 | IPersonService personService = (IPersonService) invocationProxy.bind(new PersonServiceImpl()); 43 | personService.doing(); 44 | } 45 | } 46 | ``` 47 | 48 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/proxy/IPersonService.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.proxy; 2 | 3 | public interface IPersonService { 4 | void doing(); 5 | } 6 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/proxy/InvocationProxy.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.proxy; 2 | 3 | 4 | import java.lang.reflect.InvocationHandler; 5 | import java.lang.reflect.Method; 6 | import java.lang.reflect.Proxy; 7 | 8 | // Java 1.3 动态代理 9 | public class InvocationProxy implements InvocationHandler { 10 | 11 | private Object delegate; 12 | 13 | public Object bind(Object delegate) { 14 | this.delegate = delegate; 15 | ClassLoader classLoader = delegate.getClass().getClassLoader(); 16 | Class[] clazz = delegate.getClass().getInterfaces(); 17 | return Proxy.newProxyInstance(classLoader, clazz, this::invoke); 18 | } 19 | 20 | @Override 21 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 22 | Object result = null; 23 | try { 24 | System.out.println("InvocationHandler start ..."); 25 | result = method.invoke(delegate, args); 26 | System.out.println("InvocationHandler end ..."); 27 | } catch (Exception e) { 28 | e.printStackTrace(); 29 | } 30 | return result; 31 | } 32 | 33 | // TODO Testing ... 34 | public static void main(String[] args) { 35 | InvocationProxy invocationProxy = new InvocationProxy(); 36 | IPersonService personService = (IPersonService) invocationProxy.bind(new PersonServiceImpl()); 37 | personService.doing(); 38 | } 39 | } -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/proxy/PersonServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.proxy; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by ipipman on 2021/4/14. 8 | * 9 | * @version V1.0 10 | * @Package com.ipipman.gof.example.proxy 11 | * @Description: (用一句话描述该文件做什么) 12 | * @date 2021/4/14 11:55 上午 13 | */ 14 | public class PersonServiceImpl implements IPersonService{ 15 | @Override 16 | public void doing() { 17 | System.out.println("PersonServiceImpl doing on ..."); 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/singleton/GOF-Singleton单例模式.md: -------------------------------------------------------------------------------- 1 | ### Singleton 单列模式 2 | 3 | #### 为什么要使用单例? 4 | 5 | `单例设计模式`(Singleton Design Pattern)理解起来非常简单; 6 | 7 | 一个类只允许创建一个对象(或者实例),那这个类就是一个单例类; 8 | 9 | 使用场景: 10 | 11 | > - 避免资源访问冲突; 12 | > - 表示全局唯一的类; 13 | 14 | 15 | 16 | #### 如果实现一个单例? 17 | 18 | 实现一个单例,需要关注的点有以下几个方面: 19 | 20 | > - 构造函数需要是 private 访问权限的,这样才能避免外部通过 new 创建实例; 21 | > - 考虑创建对象的线程安全问题; 22 | > - 考虑是否支持延迟加载; 23 | > - 考虑 getInstance() 性能是否高(是否加锁); 24 | 25 | 26 | 27 | #### 1. 饿汉式 28 | 29 | **饿汉式** 的实现比较简单,在类加载的时候,instance 静态实例已经创建并初始化好了,所以 instance 实例是线程安全的; 30 | 31 | 不过,这样实现方式不支持延迟加载,初始化时可能会耗性能; 32 | 33 | ```java 34 | public class IdGenerator1 { 35 | private AtomicLong id = new AtomicLong(0); 36 | private static final IdGenerator1 instance = new IdGenerator1(); 37 | private IdGenerator1() { 38 | } 39 | public static IdGenerator1 getInstance() { 40 | return instance; 41 | } 42 | public Long getId(){ 43 | return id.incrementAndGet(); 44 | } 45 | } 46 | ``` 47 | 48 | 49 | 50 | #### 2. 懒汉试 51 | 52 | 有饿汉式就有懒汉式; 53 | 54 | **懒汉式** 对于 **饿汉式** 的优势在于它支持延迟加载,不影响初始化性能; 55 | 56 | 不过懒汉试缺点也很明显,我们给 getInstance() 加了一个 synchronized 锁,导致这个方法并发度很低,性能非常差; 57 | 58 | ```java 59 | public class IdGenerator2 { 60 | private AtomicLong id = new AtomicLong(0); 61 | private static IdGenerator2 instance; 62 | private IdGenerator2() { 63 | } 64 | public static synchronized IdGenerator2 getInstance() { 65 | if (instance == null) { 66 | instance = new IdGenerator2(); 67 | } 68 | return instance; 69 | } 70 | public Long getId() { 71 | return id.incrementAndGet(); 72 | } 73 | } 74 | ``` 75 | 76 | 77 | 78 | #### 3. 双重检测 79 | 80 | 饿汉式不支持延迟加载,懒汉式有性能问题,不支持高并发; 81 | 82 | **双重检测** 兼顾了性能和延迟加载问题; 83 | 84 | 在实现方式中,只要 instance 被创建后,即便再调用 getInstance() 函数也不会再进入到加锁逻辑中了; 85 | 86 | ```java 87 | public class IdGenerator3 { 88 | private AtomicLong id = new AtomicLong(0); 89 | private static volatile IdGenerator3 instance; 90 | private IdGenerator3() { 91 | } 92 | public static IdGenerator3 getInstance() { 93 | if (instance == null) { 94 | synchronized (IdGenerator3.class) { 95 | if (instance == null) { 96 | instance = new IdGenerator3(); 97 | } 98 | } 99 | } 100 | return instance; 101 | } 102 | public Long getId() { 103 | return id.incrementAndGet(); 104 | } 105 | } 106 | ``` 107 | 108 | 109 | 110 | #### 4. 静态内部类 111 | 112 | **静态内部类** 它有点类似于饿汉模式,但又能做到延迟加载; 113 | 114 | SingletonHolder 是一个内部静态类,当外部类 IdGenerator4 被加载的时候,并不会创建 SingletonHodler 实例对象; 115 | 116 | 只有在 getInstance() 方式时,SingletonHodler 类才会被加载; 117 | 118 | instance 的唯一性、创建过程的线程安全由 JVM 来保证; 119 | 120 | ```java 121 | public class IdGenerator4 { 122 | private AtomicLong id = new AtomicLong(0); 123 | private IdGenerator4() { 124 | } 125 | private static class SingletonHolder { 126 | public final static IdGenerator4 instance = new IdGenerator4(); 127 | } 128 | public static IdGenerator4 getInstance() { 129 | return SingletonHolder.instance; 130 | } 131 | public Long getId() { 132 | return id.incrementAndGet(); 133 | } 134 | } 135 | ``` 136 | 137 | 138 | 139 | #### 5. 枚举 140 | 141 | 基于 **枚举类型** 的单例实现,这种实现方式通过 Java 枚举类型本身的特性,保证了实例创建的线程安全性和实例的唯一性; 142 | 143 | ```java 144 | public enum IdGenerator5 { 145 | INSTANCE; 146 | private AtomicLong id = new AtomicLong(0); 147 | 148 | public Long getId() { 149 | return id.incrementAndGet(); 150 | } 151 | } 152 | ``` -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/singleton/IdGenerator1.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.singleton; 2 | 3 | // 1.饿汉式 4 | // 饿汉式的实现比较简单,在类加载的时候,instance 静态实例已经创建并初始化好了,所以 instance 实例是线程安全的; 5 | // 不过,这样实现方式不支持延迟加载,初始化时可能会耗性能; 6 | 7 | import java.util.concurrent.atomic.AtomicLong; 8 | 9 | public class IdGenerator1 { 10 | 11 | private AtomicLong id = new AtomicLong(0); 12 | private static final IdGenerator1 instance = new IdGenerator1(); 13 | 14 | private IdGenerator1() { 15 | 16 | } 17 | 18 | public static IdGenerator1 getInstance() { 19 | return instance; 20 | } 21 | 22 | public Long getId(){ 23 | return id.incrementAndGet(); 24 | } 25 | 26 | // TODO Testing... 27 | public static void main(String[] args) { 28 | IdGenerator1 idGenerator1 = IdGenerator1.getInstance(); 29 | System.out.println(idGenerator1.getId()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/singleton/IdGenerator2.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.singleton; 2 | 3 | // 2.懒汉试 4 | // 有饿汉式就有懒汉式; 5 | // 懒汉式对于饿汉式的优势在于它支持延迟加载,不影响初始化性能; 6 | // 不过懒汉试缺点也很明显,我们给 getInstance() 加了一个 synchronized 锁,导致这个方法并发度很低,性能非常差; 7 | 8 | import java.util.concurrent.atomic.AtomicLong; 9 | 10 | public class IdGenerator2 { 11 | 12 | private AtomicLong id = new AtomicLong(0); 13 | private static IdGenerator2 instance; 14 | 15 | private IdGenerator2() { 16 | 17 | } 18 | 19 | public static synchronized IdGenerator2 getInstance() { 20 | if (instance == null) { 21 | instance = new IdGenerator2(); 22 | } 23 | return instance; 24 | } 25 | 26 | public Long getId() { 27 | return id.incrementAndGet(); 28 | } 29 | 30 | // TODO Testing... 31 | public static void main(String[] args) { 32 | IdGenerator2 idGenerator2 = IdGenerator2.getInstance(); 33 | System.out.println(idGenerator2.getId()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/singleton/IdGenerator3.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.singleton; 2 | 3 | import java.util.concurrent.atomic.AtomicLong; 4 | 5 | // 3.双重检测 6 | // 饿汉式不支持延迟加载,懒汉式有性能问题,不支持高并发; 7 | // 双重检测 兼顾了性能和延迟加载问题; 8 | // 在实现方式中,只要 instance 被创建后,即便再调用 getInstance() 函数也不会再进入到加锁逻辑中了; 9 | 10 | public class IdGenerator3 { 11 | 12 | private static volatile IdGenerator3 instance = null; 13 | 14 | private int generatorId = 0; 15 | 16 | private IdGenerator3(){ 17 | 18 | } 19 | 20 | public static IdGenerator3 getInstance(){ 21 | if (instance == null){ 22 | synchronized (IdGenerator3.class){ 23 | if (instance == null){ 24 | instance = new IdGenerator3(); 25 | } 26 | } 27 | } 28 | return instance; 29 | } 30 | 31 | public int getGeneratorId(){ 32 | return generatorId++; 33 | } 34 | 35 | 36 | public static void main(String[] args) { 37 | for (int i = 0; i < 10; i++) { 38 | System.out.println(IdGenerator3.getInstance().getGeneratorId()); 39 | } 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/singleton/IdGenerator4.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.singleton; 2 | 3 | import java.util.concurrent.atomic.AtomicLong; 4 | 5 | // 4. 静态内部类 6 | // 静态内部类它有点类似于饿汉模式,但又能做到延迟加载; 7 | // SingletonHolder 是一个内部静态类,当外部类 IdGenerator4 被加载的时候,并不会创建 SingletonHodler 实例对象; 8 | // 只有在 getInstance() 方式时,SingletonHodler 类才会被加载; 9 | // instance 的唯一性、创建过程的线程安全由 JVM 来保证; 10 | 11 | public class IdGenerator4 { 12 | 13 | private AtomicLong id = new AtomicLong(0); 14 | 15 | private IdGenerator4() { 16 | 17 | } 18 | 19 | private static class SingletonHolder { 20 | public final static IdGenerator4 instance = new IdGenerator4(); 21 | } 22 | 23 | public static IdGenerator4 getInstance() { 24 | return SingletonHolder.instance; 25 | } 26 | 27 | public Long getId() { 28 | return id.incrementAndGet(); 29 | } 30 | 31 | // TODO Testing ... 32 | public static void main(String[] args) { 33 | IdGenerator4 idGenerator4 = IdGenerator4.getInstance(); 34 | System.out.println(idGenerator4.getId()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/singleton/IdGenerator5.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.singleton; 2 | 3 | import java.util.concurrent.atomic.AtomicLong; 4 | 5 | // 5. 枚举 6 | // 基于 **枚举类型** 的单例实现,这种实现方式通过 Java 枚举类型本身的特性,保证了实例创建的线程安全性和实例的唯一性; 7 | public enum IdGenerator5 { 8 | 9 | INSTANCE; 10 | private AtomicLong id = new AtomicLong(0); 11 | 12 | public Long getId() { 13 | return id.incrementAndGet(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/java/com/ipipman/gof/example/solution/ArraySearchSolution.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example.solution; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * Created by ipipman on 2021/4/16. 7 | * 8 | * @version V1.0 9 | * @Package com.ipipman.gof.example.solution 10 | * @Description: (用一句话描述该文件做什么) 11 | * @date 2021/4/16 11:50 上午 12 | */ 13 | public class ArraySearchSolution { 14 | 15 | // 统计一个数字在排序数组中出现的次数 16 | public static int search(int[] nums, int target) { 17 | 18 | int l = 0, r = nums.length - 1; 19 | while (l < r) { 20 | int mid = l + (r - l) / 2; 21 | if (nums[mid] >= target) { 22 | r = mid; 23 | } else if (nums[mid] < target) { 24 | l = mid + 1; 25 | } 26 | } 27 | int count = 0; 28 | while (l < nums.length && nums[l++] == target) { 29 | count++; 30 | } 31 | return count; 32 | } 33 | 34 | public static void main(String[] args) { 35 | int[] nums = new int[]{5, 7, 7, 8, 8, 10}; 36 | Arrays.sort(nums); 37 | System.out.println(search(nums, 5)); 38 | 39 | 40 | System.out.println(longestPalindrome("abcbc")); 41 | } 42 | 43 | public static String longestPalindrome(String s) { 44 | if(s == null || s.length() < 1){ 45 | return ""; 46 | } 47 | int start = 0, end = 0; 48 | for(int i = 0; i < s.length(); i++){ 49 | int lLen = toLongestPalindromeLen(s, i, i); 50 | int rLen = toLongestPalindromeLen(s, i, i+1); 51 | int maxLen = Math.max(lLen, rLen); 52 | if (maxLen > (end - start)){ 53 | start = i - (maxLen - 1) / 2; 54 | end = i + maxLen / 2; 55 | } 56 | } 57 | return s.substring(start, end + 1); 58 | } 59 | 60 | public static int toLongestPalindromeLen(String s, int left, int right){ 61 | int l = left, r = right; 62 | while((l >= 0 && r < s.length()) && (s.charAt(l) == s.charAt(r))){ 63 | 64 | l--; 65 | r++; 66 | } 67 | return r - l - 1; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /GOF/gof-example/src/main/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/GOF/gof-example/src/main/resources/application.properties -------------------------------------------------------------------------------- /GOF/gof-example/src/test/java/com/ipipman/gof/example/GofExampleApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.ipipman.gof.example; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class GofExampleApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /GOF/设计模式一.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/GOF/设计模式一.png -------------------------------------------------------------------------------- /GOF/设计模式一.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/GOF/设计模式一.xmind -------------------------------------------------------------------------------- /GOF/设计模式三.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/GOF/设计模式三.png -------------------------------------------------------------------------------- /GOF/设计模式三.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/GOF/设计模式三.xmind -------------------------------------------------------------------------------- /GOF/设计模式二.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/GOF/设计模式二.png -------------------------------------------------------------------------------- /GOF/设计模式二.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/GOF/设计模式二.xmind -------------------------------------------------------------------------------- /JAVA8/JAVA8.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JAVA8/JAVA8.xmind -------------------------------------------------------------------------------- /JAVA8/Java8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JAVA8/Java8.png -------------------------------------------------------------------------------- /JUC/信号量.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JUC/信号量.xmind -------------------------------------------------------------------------------- /JUC/信号量(并发控制).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JUC/信号量(并发控制).png -------------------------------------------------------------------------------- /JUC/多线程基础.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JUC/多线程基础.png -------------------------------------------------------------------------------- /JUC/多线程基础.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JUC/多线程基础.xmind -------------------------------------------------------------------------------- /JUC/并发包JUC.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JUC/并发包JUC.xmind -------------------------------------------------------------------------------- /JUC/并发集合类.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JUC/并发集合类.png -------------------------------------------------------------------------------- /JUC/并发集合类.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JUC/并发集合类.xmind -------------------------------------------------------------------------------- /JUC/线程安全.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JUC/线程安全.png -------------------------------------------------------------------------------- /JUC/线程安全.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JUC/线程安全.xmind -------------------------------------------------------------------------------- /JUC/线程池.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JUC/线程池.png -------------------------------------------------------------------------------- /JUC/线程池.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JUC/线程池.xmind -------------------------------------------------------------------------------- /JVM/GC垃圾回收.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/GC垃圾回收.png -------------------------------------------------------------------------------- /JVM/GC垃圾回收.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/GC垃圾回收.xmind -------------------------------------------------------------------------------- /JVM/JDK命令行工具.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/JDK命令行工具.png -------------------------------------------------------------------------------- /JVM/JDK命令行工具.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/JDK命令行工具.xmind -------------------------------------------------------------------------------- /JVM/JVM内存模型.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/JVM内存模型.png -------------------------------------------------------------------------------- /JVM/JVM内存模型.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/JVM内存模型.xmind -------------------------------------------------------------------------------- /JVM/JVM启动参数.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/JVM启动参数.png -------------------------------------------------------------------------------- /JVM/JVM启动参数.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/JVM启动参数.xmind -------------------------------------------------------------------------------- /JVM/JVM类加载器.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/JVM类加载器.png -------------------------------------------------------------------------------- /JVM/JVM类加载器.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/JVM类加载器.xmind -------------------------------------------------------------------------------- /JVM/Java字节码技术.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/Java字节码技术.png -------------------------------------------------------------------------------- /JVM/Java字节码技术.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/JVM/Java字节码技术.xmind -------------------------------------------------------------------------------- /MQ/JMQ异步处理消息的实现.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/JMQ异步处理消息的实现.png -------------------------------------------------------------------------------- /MQ/JMQ异步处理消息的实现.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/JMQ异步处理消息的实现.xmind -------------------------------------------------------------------------------- /MQ/Kafka中Consumer源码分析.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/Kafka中Consumer源码分析.png -------------------------------------------------------------------------------- /MQ/Kafka中Consumer源码分析.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/Kafka中Consumer源码分析.xmind -------------------------------------------------------------------------------- /MQ/Kafka协调者Zookeeper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/Kafka协调者Zookeeper.png -------------------------------------------------------------------------------- /MQ/Kafka协调者Zookeeper.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/Kafka协调者Zookeeper.xmind -------------------------------------------------------------------------------- /MQ/Kafka和RocketMQ消息复制.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/Kafka和RocketMQ消息复制.png -------------------------------------------------------------------------------- /MQ/Kafka和RocketMQ消息复制.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/Kafka和RocketMQ消息复制.xmind -------------------------------------------------------------------------------- /MQ/Kafka缓存策略.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/Kafka缓存策略.png -------------------------------------------------------------------------------- /MQ/Kafka缓存策略.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/Kafka缓存策略.xmind -------------------------------------------------------------------------------- /MQ/Kafka高性能IO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/Kafka高性能IO.png -------------------------------------------------------------------------------- /MQ/Kafka高性能IO.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/Kafka高性能IO.xmind -------------------------------------------------------------------------------- /MQ/Mysql:Perf-Test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/Mysql:Perf-Test.png -------------------------------------------------------------------------------- /MQ/RocketMQ与Kafka事务.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/RocketMQ与Kafka事务.png -------------------------------------------------------------------------------- /MQ/RocketMQ与Kafka事务.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/RocketMQ与Kafka事务.xmind -------------------------------------------------------------------------------- /MQ/RocketMQ协调者NameServer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/RocketMQ协调者NameServer.png -------------------------------------------------------------------------------- /MQ/RocketMQ协调者NameServer.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/RocketMQ协调者NameServer.xmind -------------------------------------------------------------------------------- /MQ/RocketMQ的Producer源码分析.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/RocketMQ的Producer源码分析.png -------------------------------------------------------------------------------- /MQ/RocketMQ的Producer源码分析.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/RocketMQ的Producer源码分析.xmind -------------------------------------------------------------------------------- /MQ/事务消息实现分布式事务概述.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/事务消息实现分布式事务概述.png -------------------------------------------------------------------------------- /MQ/事务消息实现分布式事务概述.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/事务消息实现分布式事务概述.xmind -------------------------------------------------------------------------------- /MQ/正确的使用锁保护共享数据.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/正确的使用锁保护共享数据.png -------------------------------------------------------------------------------- /MQ/正确的使用锁保护共享数据.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/正确的使用锁保护共享数据.xmind -------------------------------------------------------------------------------- /MQ/消息队列数据丢失解决方案.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/消息队列数据丢失解决方案.png -------------------------------------------------------------------------------- /MQ/消息队列的基本概念.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/消息队列的基本概念.png -------------------------------------------------------------------------------- /MQ/消息队列的基本概念.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/MQ/消息队列的基本概念.xmind -------------------------------------------------------------------------------- /Mysql/Mysql中的日志.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql中的日志.png -------------------------------------------------------------------------------- /Mysql/Mysql中的锁.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql中的锁.png -------------------------------------------------------------------------------- /Mysql/Mysql中的锁.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql中的锁.xmind -------------------------------------------------------------------------------- /Mysql/Mysql主从.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql主从.png -------------------------------------------------------------------------------- /Mysql/Mysql主从.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql主从.xmind -------------------------------------------------------------------------------- /Mysql/Mysql事务.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql事务.png -------------------------------------------------------------------------------- /Mysql/Mysql事务.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql事务.xmind -------------------------------------------------------------------------------- /Mysql/Mysql优化.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql优化.png -------------------------------------------------------------------------------- /Mysql/Mysql优化方案.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql优化方案.xmind -------------------------------------------------------------------------------- /Mysql/Mysql架构设计.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql架构设计.png -------------------------------------------------------------------------------- /Mysql/Mysql架构设计.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql架构设计.xmind -------------------------------------------------------------------------------- /Mysql/Mysql的日志.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql的日志.xmind -------------------------------------------------------------------------------- /Mysql/Mysql索引设计.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql索引设计.png -------------------------------------------------------------------------------- /Mysql/Mysql索引设计.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/Mysql索引设计.xmind -------------------------------------------------------------------------------- /Mysql/关系型数据库.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/关系型数据库.png -------------------------------------------------------------------------------- /Mysql/关系型数据库.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/Mysql/关系型数据库.xmind -------------------------------------------------------------------------------- /NIO/Netty核心内幕.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/NIO/Netty核心内幕.png -------------------------------------------------------------------------------- /NIO/Netty线程模型.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/NIO/Netty线程模型.png -------------------------------------------------------------------------------- /NIO/Netty线程模型.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/NIO/Netty线程模型.xmind -------------------------------------------------------------------------------- /NIO/Nett核心内幕.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/NIO/Nett核心内幕.xmind -------------------------------------------------------------------------------- /NIO/常用IO模型.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/NIO/常用IO模型.png -------------------------------------------------------------------------------- /NIO/常用IO模型.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/NIO/常用IO模型.xmind -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 必读 2 | 3 | ## 一.如果没有VPN的用户,在查阅Readme文章时,需要绑定Host! 4 | 5 | ```shell script 6 | # GitHub Start 7 | 140.82.114.4 github.com 8 | 140.82.114.4 gist.github.com 9 | 185.199.108.153 assets-cdn.github.com 10 | 151.101.64.133 raw.githubusercontent.com 11 | 151.101.108.133 gist.githubusercontent.com 12 | 151.101.108.133 cloud.githubusercontent.com 13 | 151.101.108.133 camo.githubusercontent.com 14 | 151.101.108.133 avatars0.githubusercontent.com 15 | 151.101.108.133 avatars1.githubusercontent.com 16 | 151.101.108.133 avatars2.githubusercontent.com 17 | 151.101.108.133 avatars3.githubusercontent.com 18 | 151.101.108.133 avatars4.githubusercontent.com 19 | 151.101.108.133 avatars5.githubusercontent.com 20 | 151.101.108.133 avatars6.githubusercontent.com 21 | 151.101.108.133 avatars7.githubusercontent.com 22 | 151.101.108.133 avatars8.githubusercontent.com 23 | # GitHub End 24 | ``` 25 | -------------------------------------------------------------------------------- /XT/Base柔性事务.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/XT/Base柔性事务.png -------------------------------------------------------------------------------- /XT/Base柔性事务.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/XT/Base柔性事务.xmind -------------------------------------------------------------------------------- /XT/XA分布式事务.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/XT/XA分布式事务.png -------------------------------------------------------------------------------- /XT/XA分布式事务.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipipman/JavaKnowledge/f58b9393984132824074012803ebb6b813d41ec8/XT/XA分布式事务.xmind -------------------------------------------------------------------------------- /技术架构/(1)架构的标准定义.md: -------------------------------------------------------------------------------- 1 | ## 架构的标准定义 2 | 3 | 4 | 5 | ### 架构的组成部分 6 | 7 | image-20210825110357585 8 | 9 | 10 | 11 | ### 系统 & 子系统 - 定义 12 | 13 | #### 1、系统 14 | 15 | > 泛指由一群有关联的个体组成,根据某种规则运作; 16 | 17 | #### 2、子系统 18 | 19 | > 由一群有关联的个体所组成的系统,多半会是更大系统中的一部分 20 | 21 | #### 标准定义 22 | 23 | image-20210825110913049 24 | 25 | > 一群有关联的个体,个体之间按规则运作,系统的能力超越个体的能力,自顶向下逐层分解 26 | 27 | 28 | 29 | ### 模块 vs 组件 - 定义 30 | 31 | image-20210825111620645 32 | 33 | #### 1、模块 34 | 35 | > 模块是按逻辑的角度或者业务的角度进行拆分的,比如:用户模块、课程模块 36 | > 37 | > 模块可以理解为系统的个体,在系统下通过模块之前的规则运作,解决的是职责分离 38 | > 39 | > 微服务和DDD设计都属于模块在服务化场景的一种描述 40 | 41 | #### 2、组件 42 | 43 | > 组件是按物理拆分的,每个组件都能独立运行,可以服用在多个系统中 44 | > 45 | > 像Nginx、Mysql、Redis或封装的复用代码包等等,都能称为组件 46 | 47 | 48 | 49 | ### 框架 vs 架构 50 | 51 | image-20210825115240818 52 | 53 | #### 框架 54 | 55 | > 框架特指用软件产品实现了一堆组件的使用规范 56 | > 57 | > 像Spring、脚手架都属于框架 58 | 59 | #### 软件架构 60 | 61 | > 涵盖了架构本身的定义和架构文档的内容 62 | 63 | 64 | 65 | ### 4R架构定义 - Rank + Role + Relation + Rule 66 | 67 | image-20210825120033355 68 | 69 | 70 | 71 | ### 4R 架构应用 72 | 73 | image-20210826112630312 74 | 75 | 76 | 77 | ### 4R 架构思维脑图 78 | 79 | image-20210826113340582 80 | 81 | -------------------------------------------------------------------------------- /技术架构/(2)画出优秀的架构图.md: -------------------------------------------------------------------------------- 1 | ### 画出优秀的架构图 2 | 3 | #### 架构视图定义 4 | 5 | image-20210830111936192 6 | 7 | > 逻辑试图:系统提供给用户的功能,对应UML的class 和 state diagrams 8 | > 9 | > 处理试图:系统的处理过程,对应UML的sequence 和 activity diagrams 10 | > 11 | > 开发试图:程序员角度看系统的逻辑组成,对应UML 的 package diagrams 12 | > 13 | > 物理试图:系统工程师角度看系统的物理组成,对应UML 的 deployment diagrams 14 | > 15 | > 场景试图:用户角度看系统需要实现的需求,对应UML的use case diagrams 16 | 17 | 18 | 19 | 20 | 21 | #### 架构图分类 22 | 23 | image-20210831103427276 24 | 25 | 26 | 27 | #### 业务架构 28 | 29 | image-20210831104058810 30 | 31 | **业务场景使用场景:** 32 | 33 | 1、产品人员规划业务 34 | 35 | 2、给高P汇报业务 36 | 37 | 3、给新员工培训业务 38 | 39 | 40 | 41 | #### 前端和客户端架构 42 | 43 | image-20210831104945332 44 | 45 | **前端和客户端架构使用场景** 46 | 47 | 1、整体架构设计 48 | 49 | 2、架构培训 50 | 51 | 52 | 53 | #### 系统架构 - 简单 54 | 55 | image-20210831105124710 56 | 57 | > 虚线和实现的区别:弱依赖,代表不同的连接的方式,或者是不同的传输数据 58 | 59 | **系统架构使用场景:** 60 | 61 | 1、整体架构设计 62 | 63 | 2、架构培训 64 | 65 | 66 | 67 | #### 系统架构 - 复杂 68 | 69 | image-20210831142030836 70 | 71 | 72 | 73 | #### 应用架构 74 | 75 | image-20210831142340727 76 | 77 | > 应用架构和系统架构的区别:应用架构是系统架构的子级,它描述的是具体实现某些功能 78 | 79 | **应用场景使用场景:** 80 | 81 | 1、项目开发、测试 82 | 83 | 2、部署发布 84 | 85 | 3、子域架构设计 86 | 87 | 88 | 89 | #### 应用架构 - 开源案例 90 | 91 | image-20210831142717091 92 | 93 | 94 | 95 | #### 部署架构 96 | 97 | image-20210831142848855 98 | 99 | 100 | 101 | #### 系统序列图 102 | 103 | image-20210831143153892 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /技术架构/(3)面向复杂度架构设计.md: -------------------------------------------------------------------------------- 1 | ### 面向复杂度架构设计 2 | 3 | 4 | 5 | #### DDD 设计的理解 6 | 7 | > DDD 是可扩展架构的设计技巧,不是架构方法论; 8 | > 9 | > DDD 兼顾架构设计和方案设计,大部分人会搞混; 10 | > 11 | > DDD、敏捷架构不关注存储和计算,只关注业务; 12 | 13 | 14 | 15 | #### 整洁架构 16 | 17 | image-20210918111705265 18 | 19 | 20 | 21 | #### 面向复杂度架构-为什么要做架构设计? 22 | 23 | - 本质:架构设计师为了降低软件系统的复杂度; 24 | - 思路:通过分析系统需求找到系统复杂的地方,然后设计方案; 25 | - 复杂度来源:高性能、高可用、高扩展、安全、成本.... 26 | - 套路:分库分表、缓存、集群、分片、微服务、DDD、异地多活.... 27 | 28 | 29 | 30 | #### 架构设计环 31 | 32 | image-20210918145448472 33 | 34 | 35 | 36 | 37 | 38 | #### 总结 39 | 40 | image-20210918150439409 41 | 42 | -------------------------------------------------------------------------------- /技术架构/(4)如何做好架构设计.md: -------------------------------------------------------------------------------- 1 | ### 如何做好架构设计 2 | 3 | 4 | 5 | #### 架构设计三原则 6 | 7 | - 合适原则 8 | - 简单原则 9 | - 演化原则 10 | 11 | 12 | 13 | #### 架构设计原则的意义 14 | 15 | image-20210918162030684 16 | 17 | 18 | 19 | #### 架构设计三原则-合适原则 20 | 21 | - 合适原则 22 | - 合适优于业界领先 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 | image-20210920155319480 49 | 50 | 51 | 52 | #### 架构设计原则常见判断纬度 53 | 54 | - 业务 55 | - 业务当前的量级 56 | - 业务发展速度 57 | - 业务的发展形态 58 | - 团队 59 | - 团队规模 60 | - 团队能力水平 61 | - 投入资源 62 | - 技术 63 | - 已有的技术体系 64 | - 当前技术能力 65 | - 技术成熟度 66 | 67 | 68 | 69 | #### 总结 70 | 71 | image-20210920155654127 72 | 73 | 74 | 75 | --------------------------------------------------------------------------------