├── JavaWeb ├── JavaWeb.iml ├── pom.xml ├── src │ └── main │ │ ├── java │ │ ├── Hibernate │ │ │ ├── Book.java │ │ │ ├── test.java │ │ │ └── wechat │ │ │ │ ├── dao │ │ │ │ ├── UserDao.java │ │ │ │ └── impl │ │ │ │ │ └── UserDaoImpl.java │ │ │ │ └── entity │ │ │ │ └── po │ │ │ │ ├── Person.java │ │ │ │ └── User.java │ │ ├── Mybatis │ │ │ ├── FooService.java │ │ │ ├── FooServiceImpl.java │ │ │ └── UserMapper.java │ │ ├── jdbc.properties │ │ ├── log4j │ │ │ └── test.java │ │ └── rabbitmq │ │ │ ├── Consumer.java │ │ │ ├── Producer.java │ │ │ └── 消息分发 │ │ │ ├── NewTask.java │ │ │ └── Worker.java │ │ └── resources │ │ ├── Mybatis │ │ └── UserMapper.xml │ │ ├── applicationContext.xml │ │ └── hibernate.cfg.xml └── web │ └── WEB-INF │ ├── dispatcher-servlet.xml │ └── web.xml ├── Java后端系列 └── Java基础 │ ├── String和包装类.md │ ├── final关键字.md │ ├── 基本数据类型.md │ ├── 抽象类和接口.md │ └── 面向对象.md ├── NettyDemo ├── httpkids-master │ ├── .gitignore │ ├── README.md │ ├── freemarker-2.3.1.jar │ ├── freemarker-2.3.9.jar │ ├── pom.xml │ └── src │ │ └── Http │ │ ├── Http.iml │ │ ├── java │ │ └── httpkids │ │ │ ├── demo │ │ │ ├── AuthFilter.java │ │ │ ├── DemoServer.java │ │ │ ├── HelloWorld.java │ │ │ ├── MemorySession.java │ │ │ ├── PlayHandler.java │ │ │ ├── SecurityHandler.java │ │ │ ├── User.java │ │ │ ├── UserDB.java │ │ │ └── UserHandler.java │ │ │ └── server │ │ │ ├── AbortException.java │ │ │ ├── FreemarkerEngine.java │ │ │ ├── IExceptionHandler.java │ │ │ ├── IRequestFilter.java │ │ │ ├── IRequestHandler.java │ │ │ ├── IRouteable.java │ │ │ ├── ITemplateEngine.java │ │ │ ├── KidsContext.java │ │ │ ├── KidsRequest.java │ │ │ ├── KidsRequestDispatcher.java │ │ │ ├── KidsUtils.java │ │ │ ├── Router.java │ │ │ ├── StaticRequestHandler.java │ │ │ └── internal │ │ │ ├── HttpServer.java │ │ │ ├── IRequestDispatcher.java │ │ │ └── MessageCollector.java │ │ └── resources │ │ ├── log4j.properties │ │ ├── static │ │ ├── axios.min.js │ │ ├── bootstrap.min.css │ │ ├── bootstrap.min.js │ │ ├── jquery-3.3.1.slim.min.js │ │ └── popper.min.js │ │ └── tpl │ │ ├── home.ftl │ │ ├── login.ftl │ │ └── playground.ftl └── rpckids-master │ ├── .gitignore │ ├── README.md │ ├── pom.xml │ └── src │ └── rpc │ ├── java │ └── rpckids │ │ ├── client │ │ ├── MessageCollector.java │ │ ├── RPCClient.java │ │ ├── RPCException.java │ │ └── RpcFuture.java │ │ ├── common │ │ ├── Charsets.java │ │ ├── IMessageHandler.java │ │ ├── MessageDecoder.java │ │ ├── MessageEncoder.java │ │ ├── MessageHandlers.java │ │ ├── MessageInput.java │ │ ├── MessageOutput.java │ │ ├── MessageRegistry.java │ │ └── RequestId.java │ │ ├── demo │ │ ├── DemoClient.java │ │ ├── DemoServer.java │ │ ├── ExpRequest.java │ │ └── ExpResponse.java │ │ └── server │ │ ├── DefaultHandler.java │ │ ├── MessageCollector.java │ │ └── RPCServer.java │ └── rpc.iml ├── README.md ├── SpringMVC ├── SpringMVC.iml ├── pom.xml └── web │ └── WEB-INF │ ├── applicationContext.xml │ ├── dispatcher-servlet.xml │ └── web.xml ├── parent ├── .idea │ ├── artifacts │ │ ├── parent_war.xml │ │ ├── parent_war_exploded.xml │ │ ├── son2_war.xml │ │ └── son2_war_exploded.xml │ ├── compiler.xml │ ├── encodings.xml │ ├── kotlinc.xml │ ├── libraries │ │ ├── Maven__aopalliance_aopalliance_1_0.xml │ │ ├── Maven__c3p0_c3p0_0_9_1_2.xml │ │ ├── Maven__com_alibaba_druid_1_1_5.xml │ │ ├── Maven__commons_logging_commons_logging_1_2.xml │ │ ├── Maven__junit_junit_4_11.xml │ │ ├── Maven__junit_junit_4_12.xml │ │ ├── Maven__mysql_mysql_connector_java_6_0_6.xml │ │ ├── Maven__org_hamcrest_hamcrest_core_1_3.xml │ │ ├── Maven__org_mockito_mockito_core_1_10_19.xml │ │ ├── Maven__org_mybatis_mybatis_3_4_1.xml │ │ ├── Maven__org_mybatis_mybatis_spring_1_2_2.xml │ │ ├── Maven__org_objenesis_objenesis_2_1.xml │ │ ├── Maven__org_springframework_spring_aop_4_1_7_RELEASE.xml │ │ ├── Maven__org_springframework_spring_beans_4_1_7_RELEASE.xml │ │ ├── Maven__org_springframework_spring_context_4_1_7_RELEASE.xml │ │ ├── Maven__org_springframework_spring_core_4_1_4_RELEASE.xml │ │ ├── Maven__org_springframework_spring_core_4_1_7_RELEASE.xml │ │ ├── Maven__org_springframework_spring_expression_4_1_7_RELEASE.xml │ │ ├── Maven__org_springframework_spring_jdbc_4_1_7_RELEASE.xml │ │ ├── Maven__org_springframework_spring_test_4_1_4_RELEASE.xml │ │ └── Maven__org_springframework_spring_tx_4_1_7_RELEASE.xml │ ├── misc.xml │ ├── modules.xml │ ├── uiDesigner.xml │ └── workspace.xml ├── jdbc │ ├── jdbc.iml │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ ├── DaoTest.java │ │ │ ├── dao │ │ │ │ └── UserInfoDAO.java │ │ │ └── entity │ │ │ │ └── UserInfoBean.java │ │ ├── resources │ │ │ ├── h2 │ │ │ │ └── schema.sql │ │ │ ├── mybatis │ │ │ │ └── mapper │ │ │ │ │ └── UserMapper.xml │ │ │ ├── test-data-source.xml │ │ │ └── test-h2-applicationContext.xml │ │ └── webapp │ │ │ └── WEB-INF │ │ │ ├── applicationContext.xml │ │ │ ├── log4j.xml │ │ │ └── web.xml │ │ └── test │ │ └── java │ │ ├── UserInfoDAOTest.java │ │ └── UserInfoManagerImplTest.java ├── log4j │ ├── log4j.iml │ ├── pom.xml │ └── src │ │ └── main │ │ └── webapp │ │ ├── WEB-INF │ │ └── web.xml │ │ └── index.jsp ├── parent.iml ├── pom.xml ├── src │ └── main │ │ ├── java │ │ ├── Department.java │ │ ├── Employee.java │ │ ├── Student.java │ │ ├── dao │ │ │ └── UserDao.java │ │ ├── entity │ │ │ └── User.java │ │ ├── jdbcTemplate.java │ │ ├── jdbcTest.java │ │ └── test │ │ │ └── TestJDBCtemplate.java │ │ ├── resources │ │ ├── jdbc.properties │ │ └── spring.xml │ │ └── webapp │ │ ├── WEB-INF │ │ └── web.xml │ │ └── index.jsp └── target │ └── classes │ ├── Department.class │ ├── Employee.class │ ├── Student.class │ ├── jdbc.properties │ ├── jdbcTemplate.class │ ├── jdbcTest.class │ └── spring.xml ├── rabbitmq ├── pom.xml ├── rabbitmq.iml └── src │ └── main │ └── java │ ├── MsgReceiver.java │ └── MsgSender.java ├── src └── main │ └── java │ ├── com │ ├── JavaWeb │ │ └── Servlet │ │ │ ├── Filter.java │ │ │ ├── Listener.java │ │ │ └── Servlet实践.java │ ├── Java集合 │ │ └── ArrayList和Vector和Stack.java │ ├── Spring │ │ └── SpringMVC │ │ │ └── test.java │ └── jvm │ │ ├── 内存泄漏与内存溢出 │ │ ├── 内存泄漏.java │ │ └── 内存溢出.java │ │ ├── 四种引用 │ │ ├── 弱引用.java │ │ ├── 强引用.java │ │ ├── 虚引用.java │ │ └── 软引用.java │ │ └── 类加载 │ │ ├── MyClassLoader.java │ │ ├── Test2.java │ │ ├── 双亲委派模型.java │ │ ├── 类加载器.java │ │ └── 类加载方式.java │ └── resource │ └── web.xml └── static └── test.js /JavaWeb/JavaWeb.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 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 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /JavaWeb/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | groupId 8 | JavaWeb 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 16 | 1.6 17 | 1.6 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | mysql 26 | mysql-connector-java 27 | 6.0.6 28 | 29 | 30 | 31 | org.hibernate 32 | hibernate-core 33 | 5.2.10.Final 34 | 35 | 36 | 37 | org.mybatis 38 | mybatis-spring 39 | 1.3.1 40 | 41 | 42 | 43 | com.mchange 44 | c3p0 45 | 0.9.5.2 46 | 47 | 48 | org.mybatis 49 | mybatis 50 | 3.4.1 51 | 52 | 53 | com.rabbitmq 54 | amqp-client 55 | 4.1.0 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /JavaWeb/src/main/java/Hibernate/Book.java: -------------------------------------------------------------------------------- 1 | package Hibernate; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | 7 | -------------------------------------------------------------------------------- /JavaWeb/src/main/java/Hibernate/test.java: -------------------------------------------------------------------------------- 1 | package Hibernate; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | public class test { 7 | } 8 | -------------------------------------------------------------------------------- /JavaWeb/src/main/java/Hibernate/wechat/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package Hibernate.wechat.dao; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | 7 | 8 | import java.util.List; 9 | 10 | import Hibernate.wechat.entity.po.User; 11 | 12 | public interface UserDao { 13 | // 得到所有用户 14 | public List getAllUser(); 15 | 16 | // 检测用户名是否存在 17 | public boolean isExists(String username); 18 | 19 | } -------------------------------------------------------------------------------- /JavaWeb/src/main/java/Hibernate/wechat/dao/impl/UserDaoImpl.java: -------------------------------------------------------------------------------- 1 | package Hibernate.wechat.dao.impl; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import org.hibernate.Query; 10 | import org.hibernate.Session; 11 | import org.hibernate.SessionFactory; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Repository; 14 | 15 | import Hibernate.wechat.dao.UserDao; 16 | import Hibernate.wechat.entity.po.User; 17 | @Repository 18 | public class UserDaoImpl implements UserDao { 19 | //注入sessionFactory 20 | @Autowired 21 | private SessionFactory sessionFactory; 22 | 23 | @SuppressWarnings("unchecked") 24 | 25 | @Override 26 | public List getAllUser() { 27 | List userList = new ArrayList(); 28 | String hsql="from User"; 29 | Session session = sessionFactory.getCurrentSession(); 30 | Query query = session.createQuery(hsql); 31 | userList = query.list(); 32 | return userList; 33 | } 34 | 35 | @Override 36 | public boolean isExists(String username) { 37 | Query query = sessionFactory.openSession() 38 | .createQuery("from User u where u.username = :username").setParameter("username", username); 39 | System.out.println(query.list().size()); 40 | return query.list().size()>0?true:false; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /JavaWeb/src/main/java/Hibernate/wechat/entity/po/Person.java: -------------------------------------------------------------------------------- 1 | package Hibernate.wechat.entity.po; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | public class Person { 7 | } 8 | -------------------------------------------------------------------------------- /JavaWeb/src/main/java/Hibernate/wechat/entity/po/User.java: -------------------------------------------------------------------------------- 1 | package Hibernate.wechat.entity.po; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | public class User { 7 | } 8 | -------------------------------------------------------------------------------- /JavaWeb/src/main/java/Mybatis/FooService.java: -------------------------------------------------------------------------------- 1 | package Mybatis; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | public interface FooService { 7 | } 8 | -------------------------------------------------------------------------------- /JavaWeb/src/main/java/Mybatis/FooServiceImpl.java: -------------------------------------------------------------------------------- 1 | package Mybatis; 2 | 3 | import Hibernate.wechat.entity.po.User; 4 | 5 | /** 6 | * Created by 周杰伦 on 2018/6/7. 7 | */ 8 | public class FooServiceImpl implements FooService { 9 | 10 | private UserMapper userMapper; 11 | 12 | public void setUserMapper(UserMapper userMapper) { 13 | this.userMapper = userMapper; 14 | } 15 | 16 | public User doSomeBusinessStuff(String userId) { 17 | return this.userMapper.getUser(userId); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /JavaWeb/src/main/java/Mybatis/UserMapper.java: -------------------------------------------------------------------------------- 1 | package Mybatis; 2 | 3 | import Hibernate.wechat.entity.po.User; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.apache.ibatis.annotations.Select; 6 | 7 | /** 8 | * Created by 周杰伦 on 2018/6/7. 9 | */ 10 | public interface UserMapper { 11 | @Select("SELECT * FROM users WHERE id = #{userId}") 12 | User getUser(@Param("userId") String userId); 13 | } 14 | -------------------------------------------------------------------------------- /JavaWeb/src/main/java/jdbc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h2pl/MyTech/3173c26c2aa44dfb33d2c40e0aa50ba065b5eb63/JavaWeb/src/main/java/jdbc.properties -------------------------------------------------------------------------------- /JavaWeb/src/main/java/log4j/test.java: -------------------------------------------------------------------------------- 1 | package log4j; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | public class test { 7 | } 8 | -------------------------------------------------------------------------------- /JavaWeb/src/main/java/rabbitmq/Consumer.java: -------------------------------------------------------------------------------- 1 | package rabbitmq; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/19. 5 | */ 6 | import com.rabbitmq.client.Channel; 7 | import com.rabbitmq.client.Connection; 8 | import com.rabbitmq.client.ConnectionFactory; 9 | import java.io.IOException; 10 | import java.util.concurrent.TimeoutException; 11 | import com.rabbitmq.client.*; 12 | public class Consumer { 13 | 14 | public static void main(String[] args) throws IOException, TimeoutException { 15 | ConnectionFactory factory = new ConnectionFactory(); 16 | factory.setUsername("guest"); 17 | factory.setPassword("guest"); 18 | factory.setHost("localhost"); 19 | //建立到代理服务器到连接 20 | Connection conn = factory.newConnection(); 21 | //获得信道 22 | final Channel channel = conn.createChannel(); 23 | //声明交换器 24 | String exchangeName = "hello-exchange"; 25 | channel.exchangeDeclare(exchangeName, "direct", true); 26 | //声明队列 27 | String queueName = channel.queueDeclare().getQueue(); 28 | String routingKey = "hola"; 29 | //绑定队列,通过键 hola 将队列和交换器绑定起来 30 | channel.queueBind(queueName, exchangeName, routingKey); 31 | 32 | while(true) { 33 | //消费消息 34 | boolean autoAck = false; 35 | String consumerTag = ""; 36 | channel.basicConsume(queueName, autoAck, consumerTag, new DefaultConsumer(channel) { 37 | @Override 38 | public void handleDelivery(String consumerTag, 39 | Envelope envelope, 40 | AMQP.BasicProperties properties, 41 | byte[] body) throws IOException { 42 | String routingKey = envelope.getRoutingKey(); 43 | String contentType = properties.getContentType(); 44 | System.out.println("消费的路由键:" + routingKey); 45 | System.out.println("消费的内容类型:" + contentType); 46 | long deliveryTag = envelope.getDeliveryTag(); 47 | //确认消息 48 | channel.basicAck(deliveryTag, false); 49 | System.out.println("消费的消息体内容:"); 50 | String bodyStr = new String(body, "UTF-8"); 51 | System.out.println(bodyStr); 52 | 53 | } 54 | }); 55 | } 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /JavaWeb/src/main/java/rabbitmq/Producer.java: -------------------------------------------------------------------------------- 1 | package rabbitmq; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/19. 5 | */ 6 | import com.rabbitmq.client.Channel; 7 | import com.rabbitmq.client.Connection; 8 | import com.rabbitmq.client.ConnectionFactory; 9 | import java.io.IOException; 10 | import java.util.concurrent.TimeoutException; 11 | public class Producer { 12 | 13 | public static void main(String[] args) throws IOException, TimeoutException { 14 | //创建连接工厂 15 | ConnectionFactory factory = new ConnectionFactory(); 16 | factory.setUsername("guest"); 17 | factory.setPassword("guest"); 18 | //设置 RabbitMQ 地址 19 | factory.setHost("localhost"); 20 | //建立到代理服务器到连接 21 | Connection conn = factory.newConnection(); 22 | //获得信道 23 | Channel channel = conn.createChannel(); 24 | //声明交换器 25 | String exchangeName = "hello-exchange"; 26 | channel.exchangeDeclare(exchangeName, "direct", true); 27 | 28 | String routingKey = "hola"; 29 | //发布消息 30 | byte[] messageBodyBytes = "quit".getBytes(); 31 | channel.basicPublish(exchangeName, routingKey, null, messageBodyBytes); 32 | 33 | channel.close(); 34 | conn.close(); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /JavaWeb/src/main/java/rabbitmq/消息分发/NewTask.java: -------------------------------------------------------------------------------- 1 | package rabbitmq.消息分发; 2 | 3 | import com.rabbitmq.client.Channel; 4 | import com.rabbitmq.client.Connection; 5 | import com.rabbitmq.client.ConnectionFactory; 6 | 7 | import java.io.IOException; 8 | import java.util.concurrent.TimeoutException; 9 | 10 | /** 11 | * Created by 周杰伦 on 2018/6/19. 12 | */ 13 | public class NewTask { 14 | private final static String QUEUE_NAME = "hello"; 15 | 16 | public static void main(String[] args) throws IOException, TimeoutException { 17 | /** 18 | * 创建连接连接到MabbitMQ 19 | */ 20 | ConnectionFactory factory = new ConnectionFactory(); 21 | // 设置MabbitMQ所在主机ip或者主机名 22 | factory.setHost("127.0.0.1"); 23 | // 创建一个连接 24 | Connection connection = factory.newConnection(); 25 | // 创建一个频道 26 | Channel channel = connection.createChannel(); 27 | // 指定一个队列 28 | channel.queueDeclare(QUEUE_NAME, false, false, false, null); 29 | // 发送的消息 30 | String message = "Hello World..."; 31 | // 往队列中发出一条消息 32 | for (int i = 0; i < 5; i++) { 33 | // 发送的消息 34 | String smessage = "Hello World" + i; 35 | // 往队列中发出一条消息 36 | channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); 37 | System.out.println(" [x] Sent '" + message + "'"); 38 | } 39 | channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); 40 | System.out.println(" [x] Sent '" + message + "'"); 41 | // 关闭频道和连接 42 | channel.close(); 43 | connection.close(); 44 | } 45 | } -------------------------------------------------------------------------------- /JavaWeb/src/main/java/rabbitmq/消息分发/Worker.java: -------------------------------------------------------------------------------- 1 | package rabbitmq.消息分发; 2 | 3 | import com.rabbitmq.client.*; 4 | 5 | import java.io.IOException; 6 | import java.util.Date; 7 | import java.util.concurrent.TimeoutException; 8 | 9 | /** 10 | * Created by 周杰伦 on 2018/6/19. 11 | */ 12 | public class Worker { 13 | private final static String QUEUE_NAME = "hello"; 14 | 15 | public static void main(String[] argv) throws IOException, InterruptedException, TimeoutException { 16 | ConnectionFactory factory = new ConnectionFactory(); 17 | factory.setHost("127.0.0.1"); 18 | // 打开连接和创建频道,与发送端一样 19 | Connection connection = factory.newConnection(); 20 | Channel channel = connection.createChannel(); 21 | 22 | // 声明队列,主要为了防止消息接收者先运行此程序,队列还不存在时创建队列。 23 | channel.queueDeclare(QUEUE_NAME, false, false, false, null); 24 | System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); 25 | 26 | // 创建队列消费者 27 | final Consumer consumer = new DefaultConsumer(channel) { 28 | @Override 29 | public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { 30 | String message = new String(body, "UTF-8"); 31 | 32 | System.out.println(" [x] Received '" + message + "'"); 33 | System.out.println(" [x] Proccessing... at " +new Date().toLocaleString()); 34 | try { 35 | for (char ch: message.toCharArray()) { 36 | if (ch == '.') { 37 | Thread.sleep(1000); 38 | } 39 | } 40 | } catch (InterruptedException e) { 41 | } finally { 42 | System.out.println(" [x] Done! at " +new Date().toLocaleString()); 43 | } 44 | } 45 | }; 46 | channel.basicConsume(QUEUE_NAME, true, consumer); 47 | } 48 | } -------------------------------------------------------------------------------- /JavaWeb/src/main/resources/Mybatis/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | user_id, user_name, user_birthday, user_salary 12 | 13 | 19 | 20 | delete from t_user 21 | where user_id = #{userId,jdbcType=CHAR} 22 | 23 | 24 | insert into t_user (user_id, user_name, user_birthday, 25 | user_salary) 26 | values (#{userId,jdbcType=CHAR}, #{userName,jdbcType=VARCHAR}, #{userBirthday,jdbcType=DATE}, 27 | #{userSalary,jdbcType=DOUBLE}) 28 | 29 | 30 | insert into t_user 31 | 32 | 33 | user_id, 34 | 35 | 36 | user_name, 37 | 38 | 39 | user_birthday, 40 | 41 | 42 | user_salary, 43 | 44 | 45 | 46 | 47 | #{userId,jdbcType=CHAR}, 48 | 49 | 50 | #{userName,jdbcType=VARCHAR}, 51 | 52 | 53 | #{userBirthday,jdbcType=DATE}, 54 | 55 | 56 | #{userSalary,jdbcType=DOUBLE}, 57 | 58 | 59 | 60 | 61 | update t_user 62 | 63 | 64 | user_name = #{userName,jdbcType=VARCHAR}, 65 | 66 | 67 | user_birthday = #{userBirthday,jdbcType=DATE}, 68 | 69 | 70 | user_salary = #{userSalary,jdbcType=DOUBLE}, 71 | 72 | 73 | where user_id = #{userId,jdbcType=CHAR} 74 | 75 | 76 | update t_user 77 | set user_name = #{userName,jdbcType=VARCHAR}, 78 | user_birthday = #{userBirthday,jdbcType=DATE}, 79 | user_salary = #{userSalary,jdbcType=DOUBLE} 80 | where user_id = #{userId,jdbcType=CHAR} 81 | 82 | -------------------------------------------------------------------------------- /JavaWeb/src/main/resources/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | Hibernate.wechat.entity.po 27 | 28 | 29 | 30 | 31 | ${hibernate.hbm2ddl.auto} 32 | ${hibernate.dialect} 33 | ${hibernate.show_sql} 34 | ${hibernate.format_sql} 35 | false 36 | 37 | 38 | 39 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 51 | 52 | 53 | 54 | 55 | 57 | 58 | 59 | 61 | 62 | 63 | 64 | 65 | 66 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /JavaWeb/src/main/resources/hibernate.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | com.mysql.jdbc.Driver 10 | 11 | jdbc:mysql://localhost/hibernate_test 12 | 13 | root 14 | 15 | cheng 16 | 17 | 20 18 | 19 | 1 20 | 21 | 5000 22 | 23 | 100 24 | 3000 25 | 2 26 | true 27 | 28 | 29 | 30 | update 31 | 32 | true 33 | 34 | true 35 | 36 | false 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /JavaWeb/web/WEB-INF/dispatcher-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /JavaWeb/web/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | wthfeng的mvc练习项目 8 | 9 | contextConfigLocation 10 | /applicationContext.xml 11 | 12 | 13 | hello 14 | Servlet相关.Servlet.HelloServlet 15 | 1 16 | 17 | 18 | dispatcher 19 | org.springframework.web.servlet.DispatcherServlet 20 | 1 21 | 22 | 23 | hello 24 | /hello 25 | 26 | 27 | dispatcher 28 | *.form 29 | 30 | 31 | 32 | myFilter 33 | Servlet相关.Filter和listener.MyFilter 34 | 35 | myParam 36 | myValue 37 | 38 | 39 | 40 | myFilter 41 | /* 42 | 43 | 44 | 45 | 46 | org.springframework.web.context.ContextLoaderListener 47 | 48 | 49 | org.springframework.web.context.ContextLoaderListener 50 | 51 | -------------------------------------------------------------------------------- /Java后端系列/Java基础/final关键字.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: java基础4:深入理解final关键字 3 | date: 2018-04-23 11:41:32 4 | tags: 5 | - Java基础 6 | categories: 7 | - 后端 8 | - Java 9 | --- 10 | 本文主要介绍了final关键字的使用方法及原理 11 | 12 | 具体代码在我的GitHub中可以找到 13 | > https://github.com/h2pl/MyTech 14 | 15 | 文章首发于我的个人博客: 16 | > https://h2pl.github.io/2018/04/23/javase4 17 | 18 | 更多关于Java后端学习的内容请到我的CSDN博客上查看: 19 | 20 | https://blog.csdn.net/a724888 21 | 22 | 23 | > final关键字可以修饰类、方法和引用。 24 | > 25 | > 修饰类,该类不能被继承。并且这个类的对象在堆中分配内存后地址不可变。 26 | > 27 | > 修饰方法,方法不能被子类重写。 28 | > 29 | > 修饰引用,引用无法改变,对于基本类型,无法修改值,对于引用,虽然不能修改地址值,但是可以对指向对象的内部进行修改。 30 | 31 | 比如char[0] = 'a'。不改变对象内存地址,只改变了值。 32 | 33 | 具体看一下下面的栗子: 34 | 35 | 36 | final class Fi { 37 | int a; 38 | final int b = 0; 39 | Integer s; 40 | 41 | } 42 | class Si{ 43 | //一般情况下final修饰的变量一定要被初始化。 44 | //只有下面这种情况例外,要求该变量必须在构造方法中被初始化。 45 | //并且不能有空参数的构造方法。 46 | //这样就可以让每个实例都有一个不同的变量,并且这个变量在每个实例中只会被初始化一次 47 | //于是这个变量在单个实例里就是常量了。 48 | final int s ; 49 | Si(int s) { 50 | this.s = s; 51 | } 52 | } 53 | class Bi { 54 | final int a = 1; 55 | final void go() { 56 | //final修饰方法无法被继承 57 | } 58 | } 59 | class Ci extends Bi { 60 | final int a = 1; 61 | // void go() { 62 | // //final修饰方法无法被继承 63 | // } 64 | } 65 | final char[]a = {'a'}; 66 | final int[]b = {1}; 67 | 68 | ## final修饰类 69 | 70 | @Test 71 | public void final修饰类() { 72 | //引用没有被final修饰,所以是可变的。 73 | //final只修饰了Fi类型,即Fi实例化的对象在堆中内存地址是不可变的。 74 | //虽然内存地址不可变,但是可以对内部的数据做改变。 75 | Fi f = new Fi(); 76 | f.a = 1; 77 | System.out.println(f); 78 | f.a = 2; 79 | System.out.println(f); 80 | //改变实例中的值并不改变内存地址。 81 | 82 | Fi ff = f; 83 | //让引用指向新的Fi对象,原来的f对象由新的引用ff持有。 84 | //引用的指向改变也不会改变原来对象的地址 85 | f = new Fi(); 86 | System.out.println(f); 87 | System.out.println(ff); 88 | } 89 | 90 | ## final修饰方法 91 | 92 | @Test 93 | public void final修饰方法() { 94 | Bi bi = new Bi(); 95 | bi.go();//该方法无法被子类Ci重写 96 | 97 | } 98 | 99 | ## final修饰基本数据类型变量和引用 100 | 101 | @Test 102 | public void final修饰基本类型变量和引用() { 103 | final int a = 1; 104 | final int[] b = {1}; 105 | final int[] c = {1}; 106 | // b = c;报错 107 | b[0] = 1; 108 | final String aa = "a"; 109 | final Fi f = new Fi(); 110 | //aa = "b";报错 111 | // f = null;//报错 112 | f.a = 1; 113 | } 114 | 关于字符串的内容可以在上一节查看: 115 | 116 | https://blog.csdn.net/a724888/article/details/80042298 -------------------------------------------------------------------------------- /Java后端系列/Java基础/抽象类和接口.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Java基础5:抽象类和接口 3 | date: 2018-04-24 00:30:14 4 | tags: 5 | - Java基础 6 | categories: 7 | - 后端 8 | - Java 9 | --- 10 | 本文主要介绍了抽象类和接口的使用方法和区别 11 | 12 | 具体代码在我的GitHub中可以找到 13 | > https://github.com/h2pl/MyTech 14 | 15 | 文章首发于我的个人博客: 16 | > https://h2pl.github.io/2018/04/24/javase5 17 | 18 | 更多关于Java后端学习的内容请到我的CSDN博客上查看: 19 | 20 | https://blog.csdn.net/a724888 21 | 22 | >1 抽象类一般会实现一部分操作,并且留一些抽象方法让子类自己实现,比如Stringbuffer和Stringbuilder的父类abstractStringbuilder。 23 | 24 | >2 接口一般指一种规定,比如一个map接口中,可能需要实现增删改查等功能,如果你想实现一个具体map,这些方法就必须按照规定去实现。 25 | 26 | >3 另外,一个类可以实现多个接口,但是不能继承多个类。 27 | 然而接口却可以继承多个其他接口。这一点很神奇。 28 | 29 | 下面看一下具体的例子,有一些小细节平时可能不会注意。 30 | 31 | class A { 32 | 33 | } 34 | interface M extends N,L{ 35 | 36 | } 37 | interface N{ 38 | 39 | } 40 | interface L{ 41 | 42 | } 43 | interface 接口 { 44 | public final int i = 1;//变量默认都为public final修饰 45 | final A a = null;//基本数据类型和引用都一样 46 | //protected void a();//报错 47 | //private //报错 48 | public abstract void a();// 方法都是public abstract修饰的。 49 | 50 | //void b(){} 报错,接口里的方法不能有方法体,也不能有{},只能有(); 51 | 52 | // final void b(); 53 | // 注意,抽象方法不能加final。因为final方法不能被重写。 54 | //但如果抽象方法不被重写那就没有意义了,因为他根本没有代码体。 55 | 56 | } 57 | abstract class 抽象类 { 58 | public final int i = 1;//变量并没有被pulic和final修饰,只是一般的成员变量 59 | public final A a = null; 60 | 61 | private void A(){}//抽象类可以有具体方法 62 | abstract void AA();//抽象方法没有方法体 63 | 64 | //private abstract void B();//报错,组合非法 65 | // 因为private修饰的方法无法被子类重写,所以和final一样,使抽象方法无法被实现。 66 | 67 | } 68 | 69 | //抽象类也可以被实例化,举例说明 70 | abstract class B{ 71 | B() { 72 | System.out.println("b init"); 73 | } 74 | } 75 | 76 | class C extends B{ 77 | C(){ 78 | super(); 79 | System.out.println("c init"); 80 | } 81 | } 82 | 83 | public class 接口对比抽象类 { 84 | @Test 85 | public void test() { 86 | C c = new C(); 87 | //结果先实例化B,再实例化C。 88 | //因为会调用到父类的构造方法。 89 | } 90 | } -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/.gitignore: -------------------------------------------------------------------------------- 1 | .settings 2 | .project 3 | .classpath 4 | *.class 5 | target 6 | deploy 7 | dependency-reduced-pom.xml 8 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/README.md: -------------------------------------------------------------------------------- 1 | httpkids 2 | -- 3 | Web framework based on netty for kids, java10 required! 4 | 5 | Features & Disadvantages 6 | -- 7 | 1. Extremely lightweight compared with other web frameworks. 8 | 2. Extremely easy to use, Extermly low cost for learning. 9 | 3. Extremely easy to understand, With approximately 1200 lines of code. 10 | 4. No support for https yet. 11 | 5. No support for URL with restful style. 12 | 13 | HelloWorld 14 | -- 15 | ```java 16 | import httpkids.server.KidsRequestDispatcher; 17 | import httpkids.server.Router; 18 | import httpkids.server.internal.HttpServer; 19 | 20 | public class HelloWorld { 21 | 22 | public static void main(String[] args) { 23 | var rd = new KidsRequestDispatcher("/kids", new Router((ctx, req) -> { 24 | ctx.html("Hello, World"); 25 | })); 26 | new HttpServer("localhost", 8080, 2, 16, rd).start(); 27 | } 28 | 29 | } 30 | 31 | http://localhost:8080/kids 32 | ``` 33 | 34 | 35 | FullStack 36 | -- 37 | ```java 38 | import java.util.HashMap; 39 | 40 | import httpkids.server.KidsRequestDispatcher; 41 | import httpkids.server.Router; 42 | import httpkids.server.internal.HttpServer; 43 | 44 | public class HelloWorld { 45 | 46 | public static void main(String[] args) { 47 | var router = new Router((ctx, req) -> { 48 | ctx.html("Hello, World"); // 纯文本html 49 | }) 50 | .handler("/hello.json", (ctx, req) -> { 51 | ctx.json(new String[] { "Hello", "World" }); // JSON API 52 | }) 53 | .handler("/hello", (ctx, req) -> { 54 | var res = new HashMap(); 55 | res.put("req", req); 56 | ctx.render("playground.ftl", res); // 模版渲染 57 | }) 58 | .handler("/world", (ctx, req) -> { 59 | ctx.redirect("/hello"); // 302跳转 60 | }) 61 | .handler("/error", (ctx, req) -> { 62 | ctx.abort(500, "wtf"); // 异常 63 | }) 64 | .resource("/pub", "/static") // 静态资源 65 | .child("/user", () -> { // 路由嵌套 66 | return new Router((ctx, req) -> { 67 | ctx.html("Hello, World"); 68 | }) 69 | .handler("/hello.json", (ctx, req) -> { 70 | ctx.json(new String[] { "Hello", "World" }); 71 | }) 72 | .filter((ctx, req, before) -> { // 过滤器、拦截器 73 | if (before) { 74 | System.out.printf("before %s\n", req.path()); 75 | } else { 76 | System.out.printf("after %s\n", req.path()); 77 | } 78 | return true; 79 | }); 80 | }); 81 | 82 | var rd = new KidsRequestDispatcher("/kids", router); // 请求派发器 83 | rd.templateRoot("/tpl"); // 模版classpath根目录 84 | rd.exception(500, (ctx, e) -> { // 异常处理 85 | ctx.html("what the fuck it is", 500); 86 | }) 87 | .exception((ctx, e) -> { // 通用异常处理 88 | ctx.html("mother fucker!", e.getStatus().code()); 89 | }); 90 | 91 | var server = new HttpServer("localhost", 8080, 2, 16, rd); 92 | server.start(); 93 | 94 | Runtime.getRuntime().addShutdownHook(new Thread() { 95 | 96 | public void run() { 97 | server.stop(); // 优雅停机 98 | } 99 | 100 | }); 101 | } 102 | 103 | } 104 | 105 | http://localhost:8080/kids 106 | http://localhost:8080/kids/hello 107 | http://localhost:8080/kids/hello.json 108 | http://localhost:8080/kids/world 109 | http://localhost:8080/kids/error 110 | http://localhost:8080/kids/pub/bootstrap.min.css 111 | http://localhost:8080/kids/user 112 | http://localhost:8080/kids/user/hello 113 | ``` 114 | 115 | Discussion 116 | -- 117 | 关注公众号「码洞」,我们一起来聊聊这个框架 118 | 119 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/Http.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 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 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/demo/AuthFilter.java: -------------------------------------------------------------------------------- 1 | package httpkids.demo; 2 | 3 | import httpkids.server.IRequestFilter; 4 | import httpkids.server.KidsContext; 5 | import httpkids.server.KidsRequest; 6 | 7 | public class AuthFilter implements IRequestFilter { 8 | 9 | private MemorySession session; 10 | 11 | public AuthFilter(MemorySession session) { 12 | this.session = session; 13 | } 14 | 15 | @Override 16 | public boolean filter(KidsContext ctx, KidsRequest req, boolean beforeOrAfter) { 17 | if (!beforeOrAfter) { 18 | return true; 19 | } 20 | String sid = req.cookie("kids_sid"); 21 | if (sid != null) { 22 | var user = session.getUser(sid); 23 | if (user != null) { 24 | req.attr("user", user); 25 | return true; 26 | } 27 | } 28 | 29 | ctx.redirect("/security/login"); 30 | return false; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/demo/DemoServer.java: -------------------------------------------------------------------------------- 1 | package httpkids.demo; 2 | 3 | import httpkids.server.KidsRequestDispatcher; 4 | import httpkids.server.Router; 5 | import httpkids.server.internal.HttpServer; 6 | 7 | public class DemoServer { 8 | 9 | public static void main(String[] args) { 10 | UserDB db = new UserDB(); 11 | MemorySession session = new MemorySession(); 12 | 13 | var router = new Router((ctx, req) -> { 14 | ctx.redirect("/user"); 15 | }); 16 | router.resource("/pub", "/static"); 17 | router.child("/security", new SecurityHandler(db, session)); 18 | router.child("/play", new PlayHandler()); 19 | router.child("/user", new UserHandler().route().filter(new AuthFilter(session))); 20 | 21 | var rd = new KidsRequestDispatcher("/kids", router); 22 | rd.templateRoot("/tpl"); 23 | 24 | var server = new HttpServer("localhost", 8080, 2, 16, rd); 25 | server.start(); 26 | 27 | Runtime.getRuntime().addShutdownHook(new Thread() { 28 | 29 | public void run() { 30 | server.stop(); 31 | } 32 | 33 | }); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/demo/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package httpkids.demo; 2 | 3 | import java.util.HashMap; 4 | 5 | import httpkids.server.KidsRequestDispatcher; 6 | import httpkids.server.Router; 7 | import httpkids.server.internal.HttpServer; 8 | 9 | public class HelloWorld { 10 | 11 | public static void main(String[] args) { 12 | var router = new Router((ctx, req) -> { 13 | ctx.html("Hello, World"); // 纯文本html 14 | }) 15 | .handler("/hello.json", (ctx, req) -> { 16 | ctx.json(new String[] { "Hello", "World" }); // JSON API 17 | }) 18 | .handler("/hello", (ctx, req) -> { 19 | var res = new HashMap(); 20 | res.put("req", req); 21 | ctx.render("playground.ftl", res); // 模版渲染 22 | }) 23 | .handler("/world", (ctx, req) -> { 24 | ctx.redirect("/hello"); // 302跳转 25 | }) 26 | .handler("/error", (ctx, req) -> { 27 | ctx.abort(500, "wtf"); // 异常 28 | }) 29 | .resource("/pub", "/static") // 静态资源 30 | .child("/user", () -> { // 路由嵌套 31 | return new Router((ctx, req) -> { 32 | ctx.html("Hello, World"); 33 | }) 34 | .handler("/hello.json", (ctx, req) -> { 35 | ctx.json(new String[] { "Hello", "World" }); 36 | }) 37 | .filter((ctx, req, before) -> { // 过滤器、拦截器 38 | if (before) { 39 | System.out.printf("before %s\n", req.path()); 40 | } else { 41 | System.out.printf("after %s\n", req.path()); 42 | } 43 | return true; 44 | }); 45 | }); 46 | 47 | var rd = new KidsRequestDispatcher("/kids", router); // 请求派发器 48 | rd.templateRoot("/tpl"); // 模版classpath根目录 49 | rd.exception(500, (ctx, e) -> { // 异常处理 50 | ctx.html("what the fuck it is", 500); 51 | }).exception((ctx, e) -> { // 通用异常处理 52 | ctx.html("mother fucker!", e.getStatus().code()); 53 | }); 54 | 55 | var server = new HttpServer("localhost", 8080, 2, 16, rd); 56 | server.start(); 57 | 58 | Runtime.getRuntime().addShutdownHook(new Thread() { 59 | 60 | public void run() { 61 | server.stop(); // 优雅停机 62 | } 63 | 64 | }); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/demo/MemorySession.java: -------------------------------------------------------------------------------- 1 | package httpkids.demo; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class MemorySession { 7 | 8 | private Map users = new HashMap<>(); 9 | 10 | public User getUser(String sid) { 11 | return users.get(sid); 12 | } 13 | 14 | public void setUser(String sid, User user) { 15 | this.users.put(sid, user); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/demo/PlayHandler.java: -------------------------------------------------------------------------------- 1 | package httpkids.demo; 2 | 3 | import java.util.HashMap; 4 | 5 | import httpkids.server.IRouteable; 6 | import httpkids.server.KidsContext; 7 | import httpkids.server.KidsRequest; 8 | import httpkids.server.Router; 9 | 10 | public class PlayHandler implements IRouteable { 11 | 12 | public void play(KidsContext ctx, KidsRequest req) { 13 | var params = new HashMap(); 14 | params.put("req", req); 15 | ctx.render("playground.ftl", params); 16 | } 17 | 18 | @Override 19 | public Router route() { 20 | Router router = new Router(); 21 | router.handler("/", this::play); 22 | return router; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/demo/SecurityHandler.java: -------------------------------------------------------------------------------- 1 | package httpkids.demo; 2 | 3 | import java.util.UUID; 4 | 5 | import httpkids.server.IRouteable; 6 | import httpkids.server.KidsContext; 7 | import httpkids.server.KidsRequest; 8 | import httpkids.server.Router; 9 | 10 | public class SecurityHandler implements IRouteable { 11 | 12 | private UserDB db; 13 | private MemorySession session; 14 | 15 | public SecurityHandler(UserDB db, MemorySession session) { 16 | this.db = db; 17 | this.session = session; 18 | } 19 | 20 | public void getLoginPage(KidsContext ctx, KidsRequest req) { 21 | ctx.render("login.ftl"); 22 | } 23 | 24 | public void login(KidsContext ctx, KidsRequest req) { 25 | String name = req.mixedParam("name"); 26 | String passwd = req.mixedParam("passwd"); 27 | if (!db.checkAccess(name, passwd)) { 28 | ctx.abort(401, "用户名密码错误"); 29 | } 30 | User user = new User(name); 31 | String sid = UUID.randomUUID().toString(); 32 | session.setUser(sid, user); 33 | ctx.addCookie("kids_sid", sid); 34 | ctx.redirect("/user"); 35 | } 36 | 37 | @Override 38 | public Router route() { 39 | Router router = new Router(); 40 | router.handler("/login", "GET", this::getLoginPage); 41 | router.handler("/login", "POST", this::login); 42 | return router; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/demo/User.java: -------------------------------------------------------------------------------- 1 | package httpkids.demo; 2 | 3 | import java.util.concurrent.atomic.AtomicInteger; 4 | 5 | public class User { 6 | 7 | private String name; 8 | 9 | private AtomicInteger counter; 10 | 11 | public User(String name) { 12 | this.name = name; 13 | this.counter = new AtomicInteger(); 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public int getCounter() { 21 | return counter.get(); 22 | } 23 | 24 | public int incrCounter() { 25 | return this.counter.incrementAndGet(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/demo/UserDB.java: -------------------------------------------------------------------------------- 1 | package httpkids.demo; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class UserDB { 7 | 8 | private Map rows = new HashMap<>(); 9 | { 10 | rows.put("Linus", "linux"); 11 | rows.put("Neumann", "math"); 12 | rows.put("Turing", "gay"); 13 | } 14 | 15 | public boolean checkAccess(String name, String passwd) { 16 | return rows.containsKey(name) && rows.get(name).equals(passwd); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/demo/UserHandler.java: -------------------------------------------------------------------------------- 1 | package httpkids.demo; 2 | 3 | import java.util.HashMap; 4 | 5 | import httpkids.server.IRouteable; 6 | import httpkids.server.KidsContext; 7 | import httpkids.server.KidsRequest; 8 | import httpkids.server.Router; 9 | 10 | public class UserHandler implements IRouteable { 11 | 12 | public void home(KidsContext ctx, KidsRequest req) { 13 | User user = req.attr("user"); 14 | user.incrCounter(); 15 | var params = new HashMap(); 16 | params.put("user", req.attr("user")); 17 | ctx.render("home.ftl", params); 18 | } 19 | 20 | public void getCounter(KidsContext ctx, KidsRequest req) { 21 | var res = new HashMap(); 22 | User user = req.attr("user"); 23 | res.put("counter", user.getCounter()); 24 | ctx.json(res); 25 | } 26 | 27 | @Override 28 | public Router route() { 29 | Router router = new Router(); 30 | router.handler("/", "GET", this::home); 31 | router.handler("/counter.json", "GET", this::getCounter); 32 | return router; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/AbortException.java: -------------------------------------------------------------------------------- 1 | package httpkids.server; 2 | 3 | import io.netty.handler.codec.http.HttpResponseStatus; 4 | 5 | public class AbortException extends RuntimeException { 6 | 7 | private static final long serialVersionUID = 1L; 8 | private HttpResponseStatus status; 9 | private String content; 10 | 11 | public AbortException(int statusCode) { 12 | this(HttpResponseStatus.valueOf(statusCode)); 13 | } 14 | 15 | public AbortException(HttpResponseStatus status) { 16 | this(status, null, null); 17 | } 18 | 19 | public AbortException(HttpResponseStatus status, Throwable t) { 20 | this(status, null, null); 21 | } 22 | 23 | public AbortException(HttpResponseStatus status, String content) { 24 | this(status, content, null); 25 | } 26 | 27 | public AbortException(HttpResponseStatus status, String content, Throwable t) { 28 | super(t); 29 | this.status = status; 30 | this.content = status.reasonPhrase(); 31 | if (content != null) { 32 | this.content = content; 33 | } 34 | } 35 | 36 | public HttpResponseStatus getStatus() { 37 | return status; 38 | } 39 | 40 | public String getContent() { 41 | return content; 42 | } 43 | 44 | public void setContent(String content) { 45 | this.content = content; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/FreemarkerEngine.java: -------------------------------------------------------------------------------- 1 | package httpkids.server; 2 | 3 | import java.io.IOException; 4 | import java.io.StringWriter; 5 | import java.util.Map; 6 | 7 | import freemarker.template.Configuration; 8 | import freemarker.template.TemplateException; 9 | import io.netty.handler.codec.http.HttpResponseStatus; 10 | 11 | public class FreemarkerEngine implements ITemplateEngine { 12 | 13 | private Configuration config; 14 | 15 | public FreemarkerEngine(String templateRoot) { 16 | this.config = new Configuration(Configuration.VERSION_2_3_28); 17 | this.config.setClassForTemplateLoading(FreemarkerEngine.class, templateRoot); 18 | } 19 | 20 | @Override 21 | public String render(String path, Map context) { 22 | try { 23 | var template = config.getTemplate(path, "utf-8"); 24 | StringWriter writer = new StringWriter(); 25 | template.process(context, writer); 26 | return writer.toString(); 27 | } catch (IOException e) { 28 | throw new AbortException(HttpResponseStatus.INTERNAL_SERVER_ERROR); 29 | } catch (TemplateException e) { 30 | throw new AbortException(HttpResponseStatus.INTERNAL_SERVER_ERROR); 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/IExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package httpkids.server; 2 | 3 | @FunctionalInterface 4 | public interface IExceptionHandler { 5 | 6 | public void handle(KidsContext ctx, AbortException e); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/IRequestFilter.java: -------------------------------------------------------------------------------- 1 | package httpkids.server; 2 | 3 | @FunctionalInterface 4 | public interface IRequestFilter { 5 | 6 | /** 7 | * @param ctx 8 | * @param req 9 | * @param beforeOrAfter true for before, false for after 10 | * @return whether to continue filter pipeline 11 | */ 12 | public boolean filter(KidsContext ctx, KidsRequest req, boolean beforeOrAfter); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/IRequestHandler.java: -------------------------------------------------------------------------------- 1 | package httpkids.server; 2 | 3 | @FunctionalInterface 4 | public interface IRequestHandler { 5 | 6 | public void handle(KidsContext ctx, KidsRequest req); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/IRouteable.java: -------------------------------------------------------------------------------- 1 | package httpkids.server; 2 | 3 | @FunctionalInterface 4 | public interface IRouteable { 5 | 6 | public Router route(); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/ITemplateEngine.java: -------------------------------------------------------------------------------- 1 | package httpkids.server; 2 | 3 | import java.util.Map; 4 | 5 | import io.netty.handler.codec.http.HttpResponseStatus; 6 | 7 | public interface ITemplateEngine { 8 | 9 | public default String render(String path, Map context) { 10 | throw new AbortException(HttpResponseStatus.INTERNAL_SERVER_ERROR, "template root not provided"); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/KidsRequestDispatcher.java: -------------------------------------------------------------------------------- 1 | package httpkids.server; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import httpkids.server.internal.IRequestDispatcher; 10 | import io.netty.channel.ChannelHandlerContext; 11 | import io.netty.handler.codec.http.FullHttpRequest; 12 | import io.netty.handler.codec.http.HttpResponseStatus; 13 | 14 | public class KidsRequestDispatcher implements IRequestDispatcher { 15 | private final static Logger LOG = LoggerFactory.getLogger(KidsRequestDispatcher.class); 16 | 17 | private String contextRoot; 18 | private Router router; 19 | private Map exceptionHandlers = new HashMap<>(); 20 | private IExceptionHandler defaultExceptionHandler = new DefaultExceptionHandler(); 21 | 22 | private ITemplateEngine templateEngine = new ITemplateEngine() { 23 | }; 24 | 25 | static class DefaultExceptionHandler implements IExceptionHandler { 26 | 27 | @Override 28 | public void handle(KidsContext ctx, AbortException e) { 29 | if (e.getStatus().code() == 500) { 30 | LOG.error("Internal Server Error", e); 31 | } 32 | ctx.error(e.getContent(), e.getStatus().code()); 33 | } 34 | 35 | } 36 | 37 | public KidsRequestDispatcher(Router router) { 38 | this("/", router); 39 | } 40 | 41 | public KidsRequestDispatcher(String contextRoot, Router router) { 42 | this.contextRoot = KidsUtils.normalize(contextRoot); 43 | this.router = router; 44 | } 45 | 46 | public KidsRequestDispatcher templateRoot(String templateRoot) { 47 | this.templateEngine = new FreemarkerEngine(templateRoot); 48 | return this; 49 | } 50 | 51 | public String root() { 52 | return contextRoot; 53 | } 54 | 55 | public KidsRequestDispatcher exception(int code, IExceptionHandler handler) { 56 | this.exceptionHandlers.put(code, handler); 57 | return this; 58 | } 59 | 60 | public KidsRequestDispatcher exception(IExceptionHandler handler) { 61 | this.defaultExceptionHandler = handler; 62 | return this; 63 | } 64 | 65 | public void dispatch(ChannelHandlerContext channelCtx, FullHttpRequest req) { 66 | var ctx = new KidsContext(channelCtx, contextRoot, templateEngine); 67 | try { 68 | this.handleImpl(ctx, new KidsRequest(req)); 69 | } catch (AbortException e) { 70 | this.handleException(ctx, e); 71 | } catch (Exception e) { 72 | this.handleException(ctx, new AbortException(HttpResponseStatus.INTERNAL_SERVER_ERROR, e)); 73 | } finally { 74 | req.release(); 75 | } 76 | } 77 | 78 | private void handleException(KidsContext ctx, AbortException e) { 79 | var handler = this.exceptionHandlers.getOrDefault(e.getStatus().code(), defaultExceptionHandler); 80 | try { 81 | handler.handle(ctx, e); 82 | } catch (Exception ex) { 83 | this.defaultExceptionHandler.handle(ctx, new AbortException(HttpResponseStatus.INTERNAL_SERVER_ERROR, ex)); 84 | } 85 | } 86 | 87 | private void handleImpl(KidsContext ctx, KidsRequest req) throws Exception { 88 | if (req.decoderResult().isFailure()) { 89 | ctx.abort(400, "http protocol decode failed"); 90 | } 91 | if (req.relativeUri().contains("./") || req.relativeUri().contains(".\\")) { 92 | ctx.abort(400, "unsecure url not allowed"); 93 | } 94 | if (!req.relativeUri().startsWith(contextRoot)) { 95 | throw new AbortException(HttpResponseStatus.NOT_FOUND); 96 | } 97 | req.popRootUri(contextRoot); 98 | router.handle(ctx, req); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/KidsUtils.java: -------------------------------------------------------------------------------- 1 | package httpkids.server; 2 | 3 | import java.nio.charset.Charset; 4 | 5 | public class KidsUtils { 6 | 7 | public static Charset UTF8 = Charset.forName("utf8"); 8 | 9 | public static String normalize(String uri) { 10 | // "/" => "/" 11 | // "" => "/" 12 | // "/a/b/" => "/a/b" 13 | // "a/b/" => "/a/b" 14 | uri = uri.trim(); 15 | // 删除后缀的/ 16 | while (uri.endsWith("/")) { 17 | uri = uri.substring(0, uri.length() - 1); 18 | } 19 | // 删除前缀的/ 20 | while (uri.startsWith("/")) { 21 | uri = uri.substring(1); 22 | } 23 | // 前缀补充/ 24 | if (!uri.startsWith("/")) { 25 | uri = "/" + uri; 26 | } 27 | return uri; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/Router.java: -------------------------------------------------------------------------------- 1 | package httpkids.server; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import io.netty.handler.codec.http.HttpResponseStatus; 10 | 11 | public class Router { 12 | 13 | private IRequestHandler wirecardHandler; 14 | 15 | private Map subHandlers = new HashMap<>(); 16 | private Map> subMethodHandlers = new HashMap<>(); 17 | 18 | private Map subRouters = new HashMap<>(); 19 | 20 | private List filters = new ArrayList<>(); 21 | 22 | private final static List METHODS = Arrays 23 | .asList(new String[] { "get", "post", "head", "put", "delete", "trace", "options", "patch", "connect" }); 24 | 25 | public Router() { 26 | this(null); 27 | } 28 | 29 | public Router(IRequestHandler wirecardHandler) { 30 | this.wirecardHandler = wirecardHandler; 31 | } 32 | 33 | public Router handler(String path, IRequestHandler handler) { 34 | path = KidsUtils.normalize(path); 35 | if (path.indexOf('/') != path.lastIndexOf('/')) { 36 | throw new IllegalArgumentException("path at most one slash allowed"); 37 | } 38 | this.subHandlers.put(path, handler); 39 | return this; 40 | } 41 | 42 | public Router handler(String path, String method, IRequestHandler handler) { 43 | path = KidsUtils.normalize(path); 44 | method = method.toLowerCase(); 45 | if (path.indexOf('/') != path.lastIndexOf('/')) { 46 | throw new IllegalArgumentException("path at most one slash allowed"); 47 | } 48 | if (!METHODS.contains(method)) { 49 | throw new IllegalArgumentException("illegal http method name"); 50 | } 51 | var handlers = subMethodHandlers.get(path); 52 | if (handlers == null) { 53 | handlers = new HashMap<>(); 54 | subMethodHandlers.put(path, handlers); 55 | } 56 | handlers.put(method, handler); 57 | return this; 58 | } 59 | 60 | public Router child(String path, Router router) { 61 | path = KidsUtils.normalize(path); 62 | if (path.equals("/")) { 63 | throw new IllegalArgumentException("child path should not be /"); 64 | } 65 | if (path.indexOf('/') != path.lastIndexOf('/')) { 66 | throw new IllegalArgumentException("path at most one slash allowed"); 67 | } 68 | this.subRouters.put(path, router); 69 | return this; 70 | } 71 | 72 | public Router child(String path, IRouteable routeable) { 73 | return child(path, routeable.route()); 74 | } 75 | 76 | public Router resource(String path, String resourceRoot) { 77 | Router router = new Router(new StaticRequestHandler(resourceRoot)); 78 | return child(path, router); 79 | } 80 | 81 | public Router resource(String path, String resourceRoot, boolean classpath) { 82 | Router router = new Router(new StaticRequestHandler(resourceRoot, classpath)); 83 | return child(path, router); 84 | } 85 | 86 | public Router resource(String path, String resourceRoot, boolean classpath, int cacheAge) { 87 | Router router = new Router(new StaticRequestHandler(resourceRoot, classpath, cacheAge)); 88 | return child(path, router); 89 | } 90 | 91 | public Router filter(IRequestFilter... filters) { 92 | for (var filter : filters) { 93 | this.filters.add(filter); 94 | } 95 | return this; 96 | } 97 | 98 | public void handle(KidsContext ctx, KidsRequest req) { 99 | for (var filter : filters) { 100 | req.filter(filter); 101 | } 102 | var prefix = req.peekUriPrefix(); 103 | var method = req.method().toLowerCase(); 104 | var router = subRouters.get(prefix); 105 | if (router != null) { 106 | req.popUriPrefix(); 107 | router.handle(ctx, req); 108 | return; 109 | } 110 | 111 | if (prefix.equals(req.relativeUri())) { 112 | var handlers = subMethodHandlers.get(prefix); 113 | IRequestHandler handler = null; 114 | if (handlers != null) { 115 | handler = handlers.get(method); 116 | } 117 | if (handler == null) { 118 | handler = subHandlers.get(prefix); 119 | } 120 | if (handler != null) { 121 | handleImpl(handler, ctx, req); 122 | return; 123 | } 124 | } 125 | 126 | if (this.wirecardHandler != null) { 127 | handleImpl(wirecardHandler, ctx, req); 128 | return; 129 | } 130 | 131 | throw new AbortException(HttpResponseStatus.NOT_FOUND); 132 | } 133 | 134 | private void handleImpl(IRequestHandler handler, KidsContext ctx, KidsRequest req) { 135 | for (var filter : req.filters()) { 136 | if (!filter.filter(ctx, req, true)) { 137 | return; 138 | } 139 | } 140 | 141 | handler.handle(ctx, req); 142 | 143 | for (var filter : req.filters()) { 144 | if (!filter.filter(ctx, req, false)) { 145 | return; 146 | } 147 | } 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/internal/HttpServer.java: -------------------------------------------------------------------------------- 1 | package httpkids.server.internal; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import io.netty.bootstrap.ServerBootstrap; 7 | import io.netty.channel.Channel; 8 | import io.netty.channel.ChannelInitializer; 9 | import io.netty.channel.ChannelOption; 10 | import io.netty.channel.EventLoopGroup; 11 | import io.netty.channel.nio.NioEventLoopGroup; 12 | import io.netty.channel.socket.SocketChannel; 13 | import io.netty.channel.socket.nio.NioServerSocketChannel; 14 | import io.netty.handler.codec.http.HttpObjectAggregator; 15 | import io.netty.handler.codec.http.HttpServerCodec; 16 | import io.netty.handler.stream.ChunkedWriteHandler; 17 | import io.netty.handler.timeout.ReadTimeoutHandler; 18 | 19 | public class HttpServer { 20 | private final static Logger LOG = LoggerFactory.getLogger(HttpServer.class); 21 | 22 | private String ip; 23 | private int port; 24 | private int ioThreads; 25 | private int workerThreads; 26 | private IRequestDispatcher dispatcher; 27 | 28 | public HttpServer(String ip, int port, int ioThreads, int workerThreads, IRequestDispatcher dispatcher) { 29 | this.ip = ip; 30 | this.port = port; 31 | this.ioThreads = ioThreads; 32 | this.workerThreads = workerThreads; 33 | this.dispatcher = dispatcher; 34 | } 35 | 36 | private ServerBootstrap bootstrap; 37 | private EventLoopGroup group; 38 | private Channel serverChannel; 39 | private MessageCollector collector; 40 | 41 | public void start() { 42 | bootstrap = new ServerBootstrap(); 43 | group = new NioEventLoopGroup(ioThreads); 44 | bootstrap.group(group); 45 | collector = new MessageCollector(workerThreads, dispatcher); 46 | bootstrap.channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer() { 47 | @Override 48 | public void initChannel(SocketChannel ch) throws Exception { 49 | var pipe = ch.pipeline(); 50 | pipe.addLast(new ReadTimeoutHandler(10)); 51 | pipe.addLast(new HttpServerCodec()); 52 | pipe.addLast(new HttpObjectAggregator(1 << 30)); // max_size = 1g 53 | pipe.addLast(new ChunkedWriteHandler()); 54 | pipe.addLast(collector); 55 | } 56 | }); 57 | bootstrap.option(ChannelOption.SO_BACKLOG, 100).option(ChannelOption.SO_REUSEADDR, true) 58 | .option(ChannelOption.TCP_NODELAY, true).childOption(ChannelOption.SO_KEEPALIVE, true); 59 | serverChannel = bootstrap.bind(this.ip, this.port).channel(); 60 | LOG.warn("server started @ {}:{}", ip, port); 61 | } 62 | 63 | public void stop() { 64 | // 先关闭服务端套件字 65 | serverChannel.close(); 66 | // 再斩断消息来源,停止io线程池 67 | group.shutdownGracefully(); 68 | // 停止业务线程池 69 | collector.closeGracefully(); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/internal/IRequestDispatcher.java: -------------------------------------------------------------------------------- 1 | package httpkids.server.internal; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.handler.codec.http.FullHttpRequest; 5 | 6 | public interface IRequestDispatcher { 7 | 8 | public void dispatch(ChannelHandlerContext ctx, FullHttpRequest req); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/java/httpkids/server/internal/MessageCollector.java: -------------------------------------------------------------------------------- 1 | package httpkids.server.internal; 2 | 3 | import java.util.concurrent.ArrayBlockingQueue; 4 | import java.util.concurrent.ThreadFactory; 5 | import java.util.concurrent.ThreadPoolExecutor; 6 | import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy; 7 | import java.util.concurrent.TimeUnit; 8 | import java.util.concurrent.atomic.AtomicInteger; 9 | import java.util.zip.CRC32; 10 | 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import io.netty.channel.ChannelHandler.Sharable; 15 | import io.netty.channel.ChannelHandlerContext; 16 | import io.netty.channel.ChannelInboundHandlerAdapter; 17 | import io.netty.handler.codec.http.FullHttpRequest; 18 | 19 | @Sharable 20 | public class MessageCollector extends ChannelInboundHandlerAdapter { 21 | private final static Logger LOG = LoggerFactory.getLogger(MessageCollector.class); 22 | 23 | private ThreadPoolExecutor[] executors; 24 | private IRequestDispatcher dispatcher; 25 | private int requestsMaxInflight = 1000; 26 | 27 | public MessageCollector(int workerThreads, IRequestDispatcher dispatcher) { 28 | var factory = new ThreadFactory() { 29 | 30 | AtomicInteger seq = new AtomicInteger(); 31 | 32 | @Override 33 | public Thread newThread(Runnable r) { 34 | Thread t = new Thread(r); 35 | t.setName("http-" + seq.getAndIncrement()); 36 | return t; 37 | } 38 | 39 | }; 40 | 41 | this.executors = new ThreadPoolExecutor[workerThreads]; 42 | for (int i = 0; i < workerThreads; i++) { 43 | var queue = new ArrayBlockingQueue(requestsMaxInflight); 44 | this.executors[i] = new ThreadPoolExecutor(1, 1, 30, TimeUnit.SECONDS, queue, factory, 45 | new CallerRunsPolicy()); 46 | } 47 | this.dispatcher = dispatcher; 48 | } 49 | 50 | public void closeGracefully() { 51 | for (var i = 0; i < executors.length; i++) { 52 | var executor = executors[i]; 53 | executor.shutdown(); 54 | } 55 | for (var i = 0; i < executors.length; i++) { 56 | var executor = executors[i]; 57 | try { 58 | executor.awaitTermination(10, TimeUnit.SECONDS); 59 | } catch (InterruptedException e) { 60 | } 61 | executor.shutdownNow(); 62 | } 63 | } 64 | 65 | @Override 66 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 67 | LOG.info("connection comes {}", ctx.channel().remoteAddress()); 68 | } 69 | 70 | @Override 71 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 72 | LOG.info("connection leaves {}", ctx.channel().remoteAddress()); 73 | ctx.close(); 74 | } 75 | 76 | @Override 77 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 78 | if (msg instanceof FullHttpRequest) { 79 | var req = (FullHttpRequest) msg; 80 | var crc32 = new CRC32(); 81 | crc32.update(ctx.hashCode()); 82 | int idx = (int) (crc32.getValue() % executors.length); 83 | this.executors[idx].execute(() -> { 84 | dispatcher.dispatch(ctx, req); 85 | }); 86 | } 87 | } 88 | 89 | @Override 90 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 91 | ctx.close(); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, stdout 2 | 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.Threshold=INFO 5 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.stdout.layout.ConversionPattern=%d{yyy-MM-dd HH:mm:ss} [%t] %-5p %c{1} %M %L %x - %m%n -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/resources/tpl/home.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |

Hello, ${user.name}

15 |

You have access this page for ${user.counter} times

16 |
17 |

Let play something here

18 |
19 |
20 | 21 | 30 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/resources/tpl/login.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 17 |
18 |
19 | 20 |
21 |
22 | 23 |
24 |
25 |
26 |
27 | 28 | -------------------------------------------------------------------------------- /NettyDemo/httpkids-master/src/Http/resources/tpl/playground.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |

PlayGround it is

15 |
16 | <#list req.allParams() as name, values> 17 | <#list values as value> 18 | ${name} = ${value}
19 | 20 | 21 |
22 |
23 | 24 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/.gitignore: -------------------------------------------------------------------------------- 1 | .settings 2 | .project 3 | .classpath 4 | *.class 5 | target 6 | deploy 7 | dependency-reduced-pom.xml 8 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/README.md: -------------------------------------------------------------------------------- 1 | rpckids 2 | -- 3 | RPC framework based on netty for kids 4 | 5 | Feature 6 | -- 7 | 1. Extremely lightweight compared with other rpc frameworks. 8 | 2. Extremely easy to use, Extermly low cost for learning. 9 | 3. Extremely easy to understand, With approximately 800 lines of code. 10 | 4. Base on JSON protocol 11 | 12 | Hello Server 13 | -- 14 | ```java 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | import io.netty.channel.ChannelHandlerContext; 19 | import rpckids.server.IMessageHandler; 20 | import rpckids.server.MessageOutput; 21 | import rpckids.server.RPCServer; 22 | 23 | class FibRequestHandler implements IMessageHandler { 24 | 25 | private List fibs = new ArrayList<>(); 26 | 27 | { 28 | fibs.add(1L); // fib(0) = 1 29 | fibs.add(1L); // fib(1) = 1 30 | } 31 | 32 | @Override 33 | public void handle(ChannelHandlerContext ctx, String requestId, Integer n) { 34 | for (int i = fibs.size(); i < n + 1; i++) { 35 | long value = fibs.get(i - 2) + fibs.get(i - 1); 36 | fibs.add(value); 37 | } 38 | ctx.writeAndFlush(new MessageOutput(requestId, "fib_res", fibs.get(n))); 39 | } 40 | 41 | } 42 | 43 | public class DemoServer { 44 | 45 | public static void main(String[] args) { 46 | RPCServer server = new RPCServer("localhost", 8888, 2, 16); 47 | server.service("fib", Integer.class, new FibRequestHandler()); 48 | server.start(); 49 | } 50 | 51 | } 52 | ``` 53 | 54 | Hello Client 55 | -- 56 | ```java 57 | import rpckids.client.RPCClient; 58 | 59 | public class DemoClient { 60 | 61 | private RPCClient client; 62 | 63 | public DemoClient(RPCClient client) { 64 | this.client = client; 65 | this.client.rpc("fib_res", Long.class).rpc("exp_res", ExpResponse.class); 66 | } 67 | 68 | public long fib(int n) { 69 | return (Long) client.send("fib", n); 70 | } 71 | 72 | public static void main(String[] args) { 73 | RPCClient client = new RPCClient("localhost", 8888); 74 | DemoClient demo = new DemoClient(client); 75 | for (int i = 0; i < 20; i++) { 76 | System.out.printf("fib(%d) = %d\n", i, demo.fib(i)); 77 | } 78 | } 79 | 80 | } 81 | ``` 82 | 83 | Discussion 84 | -- 85 | 关注公众号「码洞」,我们一起来聊聊这个框架 86 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/client/MessageCollector.java: -------------------------------------------------------------------------------- 1 | package rpckids.client; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | import java.util.concurrent.ConcurrentMap; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import io.netty.channel.ChannelHandler.Sharable; 11 | import io.netty.channel.ChannelHandlerContext; 12 | import io.netty.channel.ChannelInboundHandlerAdapter; 13 | import rpckids.common.MessageInput; 14 | import rpckids.common.MessageOutput; 15 | import rpckids.common.MessageRegistry; 16 | 17 | @Sharable 18 | public class MessageCollector extends ChannelInboundHandlerAdapter { 19 | 20 | private final static Logger LOG = LoggerFactory.getLogger(MessageCollector.class); 21 | 22 | private MessageRegistry registry; 23 | private RPCClient client; 24 | private ChannelHandlerContext context; 25 | private ConcurrentMap> pendingTasks = new ConcurrentHashMap<>(); 26 | 27 | private Throwable ConnectionClosed = new Exception("rpc connection not active error"); 28 | 29 | public MessageCollector(MessageRegistry registry, RPCClient client) { 30 | this.registry = registry; 31 | this.client = client; 32 | } 33 | 34 | @Override 35 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 36 | this.context = ctx; 37 | } 38 | 39 | @Override 40 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 41 | this.context = null; 42 | pendingTasks.forEach((__, future) -> { 43 | future.fail(ConnectionClosed); 44 | }); 45 | pendingTasks.clear(); 46 | // 尝试重连 47 | ctx.channel().eventLoop().schedule(() -> { 48 | client.reconnect(); 49 | }, 1, TimeUnit.SECONDS); 50 | } 51 | 52 | public RpcFuture send(MessageOutput output) { 53 | ChannelHandlerContext ctx = context; 54 | RpcFuture future = new RpcFuture(); 55 | if (ctx != null) { 56 | ctx.channel().eventLoop().execute(() -> { 57 | pendingTasks.put(output.getRequestId(), future); 58 | ctx.writeAndFlush(output); 59 | }); 60 | } else { 61 | future.fail(ConnectionClosed); 62 | } 63 | return future; 64 | } 65 | 66 | @Override 67 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 68 | if (!(msg instanceof MessageInput)) { 69 | return; 70 | } 71 | MessageInput input = (MessageInput) msg; 72 | // 业务逻辑在这里 73 | Class clazz = registry.get(input.getType()); 74 | if (clazz == null) { 75 | LOG.error("unrecognized msg type {}", input.getType()); 76 | return; 77 | } 78 | Object o = input.getPayload(clazz); 79 | @SuppressWarnings("unchecked") 80 | RpcFuture future = (RpcFuture) pendingTasks.remove(input.getRequestId()); 81 | if (future == null) { 82 | LOG.error("future not found with type {}", input.getType()); 83 | return; 84 | } 85 | future.success(o); 86 | } 87 | 88 | @Override 89 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 90 | 91 | } 92 | 93 | public void close() { 94 | ChannelHandlerContext ctx = context; 95 | if (ctx != null) { 96 | ctx.close(); 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/client/RPCClient.java: -------------------------------------------------------------------------------- 1 | package rpckids.client; 2 | 3 | import java.util.concurrent.ExecutionException; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import io.netty.bootstrap.Bootstrap; 10 | import io.netty.channel.ChannelInitializer; 11 | import io.netty.channel.ChannelOption; 12 | import io.netty.channel.ChannelPipeline; 13 | import io.netty.channel.EventLoopGroup; 14 | import io.netty.channel.nio.NioEventLoopGroup; 15 | import io.netty.channel.socket.SocketChannel; 16 | import io.netty.channel.socket.nio.NioSocketChannel; 17 | import io.netty.handler.timeout.ReadTimeoutHandler; 18 | import rpckids.common.MessageDecoder; 19 | import rpckids.common.MessageEncoder; 20 | import rpckids.common.MessageOutput; 21 | import rpckids.common.MessageRegistry; 22 | import rpckids.common.RequestId; 23 | 24 | public class RPCClient { 25 | private final static Logger LOG = LoggerFactory.getLogger(RPCClient.class); 26 | 27 | private String ip; 28 | private int port; 29 | private Bootstrap bootstrap; 30 | private EventLoopGroup group; 31 | private MessageCollector collector; 32 | private boolean started; 33 | private boolean stopped; 34 | 35 | private MessageRegistry registry = new MessageRegistry(); 36 | 37 | public RPCClient(String ip, int port) { 38 | this.ip = ip; 39 | this.port = port; 40 | this.init(); 41 | } 42 | 43 | public RPCClient rpc(String type, Class reqClass) { 44 | registry.register(type, reqClass); 45 | return this; 46 | } 47 | 48 | public RpcFuture sendAsync(String type, Object payload) { 49 | if (!started) { 50 | connect(); 51 | started = true; 52 | } 53 | String requestId = RequestId.next(); 54 | MessageOutput output = new MessageOutput(requestId, type, payload); 55 | return collector.send(output); 56 | } 57 | 58 | public T send(String type, Object payload) { 59 | RpcFuture future = sendAsync(type, payload); 60 | try { 61 | return future.get(); 62 | } catch (InterruptedException | ExecutionException e) { 63 | throw new RPCException(e); 64 | } 65 | } 66 | 67 | public void init() { 68 | bootstrap = new Bootstrap(); 69 | group = new NioEventLoopGroup(1); 70 | bootstrap.group(group); 71 | MessageEncoder encoder = new MessageEncoder(); 72 | collector = new MessageCollector(registry, this); 73 | bootstrap.channel(NioSocketChannel.class).handler(new ChannelInitializer() { 74 | 75 | @Override 76 | protected void initChannel(SocketChannel ch) throws Exception { 77 | ChannelPipeline pipe = ch.pipeline(); 78 | pipe.addLast(new ReadTimeoutHandler(60)); 79 | pipe.addLast(new MessageDecoder()); 80 | pipe.addLast(encoder); 81 | pipe.addLast(collector); 82 | } 83 | 84 | }); 85 | bootstrap.option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, true); 86 | } 87 | 88 | public void connect() { 89 | bootstrap.connect(ip, port).syncUninterruptibly(); 90 | } 91 | 92 | public void reconnect() { 93 | if (stopped) { 94 | return; 95 | } 96 | bootstrap.connect(ip, port).addListener(future -> { 97 | if (future.isSuccess()) { 98 | return; 99 | } 100 | if (!stopped) { 101 | group.schedule(() -> { 102 | reconnect(); 103 | }, 1, TimeUnit.SECONDS); 104 | } 105 | LOG.error("connect {}:{} failure", ip, port, future.cause()); 106 | }); 107 | } 108 | 109 | public void close() { 110 | stopped = true; 111 | collector.close(); 112 | group.shutdownGracefully(0, 5000, TimeUnit.SECONDS); 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/client/RPCException.java: -------------------------------------------------------------------------------- 1 | package rpckids.client; 2 | 3 | public class RPCException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public RPCException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | 11 | public RPCException(String message) { 12 | super(message); 13 | } 14 | 15 | public RPCException(Throwable cause) { 16 | super(cause); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/client/RpcFuture.java: -------------------------------------------------------------------------------- 1 | package rpckids.client; 2 | 3 | import java.util.concurrent.CountDownLatch; 4 | import java.util.concurrent.ExecutionException; 5 | import java.util.concurrent.Future; 6 | import java.util.concurrent.TimeUnit; 7 | import java.util.concurrent.TimeoutException; 8 | 9 | public class RpcFuture implements Future { 10 | 11 | private T result; 12 | private Throwable error; 13 | private CountDownLatch latch = new CountDownLatch(1); 14 | 15 | @Override 16 | public boolean cancel(boolean mayInterruptIfRunning) { 17 | return false; 18 | } 19 | 20 | @Override 21 | public boolean isCancelled() { 22 | return false; 23 | } 24 | 25 | @Override 26 | public boolean isDone() { 27 | return result != null || error != null; 28 | } 29 | 30 | public void success(T result) { 31 | this.result = result; 32 | latch.countDown(); 33 | } 34 | 35 | public void fail(Throwable error) { 36 | this.error = error; 37 | latch.countDown(); 38 | } 39 | 40 | @Override 41 | public T get() throws InterruptedException, ExecutionException { 42 | latch.await(); 43 | if (error != null) { 44 | throw new ExecutionException(error); 45 | } 46 | return result; 47 | } 48 | 49 | @Override 50 | public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { 51 | latch.await(timeout, unit); 52 | if (error != null) { 53 | throw new ExecutionException(error); 54 | } 55 | return result; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/common/Charsets.java: -------------------------------------------------------------------------------- 1 | package rpckids.common; 2 | 3 | import java.nio.charset.Charset; 4 | 5 | public class Charsets { 6 | 7 | public static Charset UTF8 = Charset.forName("utf8"); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/common/IMessageHandler.java: -------------------------------------------------------------------------------- 1 | package rpckids.common; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | 5 | @FunctionalInterface 6 | public interface IMessageHandler { 7 | 8 | void handle(ChannelHandlerContext ctx, String requestId, T message); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/common/MessageDecoder.java: -------------------------------------------------------------------------------- 1 | package rpckids.common; 2 | 3 | import java.util.List; 4 | 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.handler.codec.DecoderException; 8 | import io.netty.handler.codec.ReplayingDecoder; 9 | 10 | public class MessageDecoder extends ReplayingDecoder { 11 | 12 | @Override 13 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { 14 | String requestId = readStr(in); 15 | String type = readStr(in); 16 | String content = readStr(in); 17 | out.add(new MessageInput(type, requestId, content)); 18 | } 19 | 20 | private String readStr(ByteBuf in) { 21 | int len = in.readInt(); 22 | if (len < 0 || len > (1 << 20)) { 23 | throw new DecoderException("string too long len=" + len); 24 | } 25 | byte[] bytes = new byte[len]; 26 | in.readBytes(bytes); 27 | return new String(bytes, Charsets.UTF8); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/common/MessageEncoder.java: -------------------------------------------------------------------------------- 1 | package rpckids.common; 2 | 3 | import java.util.List; 4 | 5 | import com.alibaba.fastjson.JSON; 6 | 7 | import io.netty.buffer.ByteBuf; 8 | import io.netty.buffer.PooledByteBufAllocator; 9 | import io.netty.channel.ChannelHandler.Sharable; 10 | import io.netty.channel.ChannelHandlerContext; 11 | import io.netty.handler.codec.MessageToMessageEncoder; 12 | 13 | @Sharable 14 | public class MessageEncoder extends MessageToMessageEncoder { 15 | 16 | @Override 17 | protected void encode(ChannelHandlerContext ctx, MessageOutput msg, List out) throws Exception { 18 | ByteBuf buf = PooledByteBufAllocator.DEFAULT.directBuffer(); 19 | writeStr(buf, msg.getRequestId()); 20 | writeStr(buf, msg.getType()); 21 | writeStr(buf, JSON.toJSONString(msg.getPayload())); 22 | out.add(buf); 23 | } 24 | 25 | private void writeStr(ByteBuf buf, String s) { 26 | buf.writeInt(s.length()); 27 | buf.writeBytes(s.getBytes(Charsets.UTF8)); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/common/MessageHandlers.java: -------------------------------------------------------------------------------- 1 | package rpckids.common; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class MessageHandlers { 7 | 8 | private Map> handlers = new HashMap<>(); 9 | private IMessageHandler defaultHandler; 10 | 11 | public void register(String type, IMessageHandler handler) { 12 | handlers.put(type, handler); 13 | } 14 | 15 | public MessageHandlers defaultHandler(IMessageHandler defaultHandler) { 16 | this.defaultHandler = defaultHandler; 17 | return this; 18 | } 19 | 20 | public IMessageHandler defaultHandler() { 21 | return defaultHandler; 22 | } 23 | 24 | public IMessageHandler get(String type) { 25 | IMessageHandler handler = handlers.get(type); 26 | return handler; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/common/MessageInput.java: -------------------------------------------------------------------------------- 1 | package rpckids.common; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | 5 | public class MessageInput { 6 | private String type; 7 | private String requestId; 8 | private String payload; 9 | 10 | public MessageInput(String type, String requestId, String payload) { 11 | this.type = type; 12 | this.requestId = requestId; 13 | this.payload = payload; 14 | } 15 | 16 | public String getType() { 17 | return type; 18 | } 19 | 20 | public String getRequestId() { 21 | return requestId; 22 | } 23 | 24 | public T getPayload(Class clazz) { 25 | if (payload == null) { 26 | return null; 27 | } 28 | return JSON.parseObject(payload, clazz); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/common/MessageOutput.java: -------------------------------------------------------------------------------- 1 | package rpckids.common; 2 | 3 | public class MessageOutput { 4 | 5 | private String requestId; 6 | private String type; 7 | private Object payload; 8 | 9 | public MessageOutput(String requestId, String type, Object payload) { 10 | this.requestId = requestId; 11 | this.type = type; 12 | this.payload = payload; 13 | } 14 | 15 | public String getType() { 16 | return this.type; 17 | } 18 | 19 | public String getRequestId() { 20 | return requestId; 21 | } 22 | 23 | public Object getPayload() { 24 | return payload; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/common/MessageRegistry.java: -------------------------------------------------------------------------------- 1 | package rpckids.common; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class MessageRegistry { 7 | private Map> clazzes = new HashMap<>(); 8 | 9 | public void register(String type, Class clazz) { 10 | clazzes.put(type, clazz); 11 | } 12 | 13 | public Class get(String type) { 14 | return clazzes.get(type); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/common/RequestId.java: -------------------------------------------------------------------------------- 1 | package rpckids.common; 2 | 3 | import java.util.UUID; 4 | 5 | public class RequestId { 6 | 7 | public static String next() { 8 | return UUID.randomUUID().toString(); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/demo/DemoClient.java: -------------------------------------------------------------------------------- 1 | package rpckids.demo; 2 | 3 | import rpckids.client.RPCClient; 4 | import rpckids.client.RPCException; 5 | 6 | public class DemoClient { 7 | 8 | private RPCClient client; 9 | 10 | public DemoClient(RPCClient client) { 11 | this.client = client; 12 | this.client.rpc("fib_res", Long.class).rpc("exp_res", ExpResponse.class); 13 | } 14 | 15 | public long fib(int n) { 16 | return (Long) client.send("fib", n); 17 | } 18 | 19 | public ExpResponse exp(int base, int exp) { 20 | return (ExpResponse) client.send("exp", new ExpRequest(base, exp)); 21 | } 22 | 23 | public static void main(String[] args) throws InterruptedException { 24 | RPCClient client = new RPCClient("localhost", 8888); 25 | DemoClient demo = new DemoClient(client); 26 | for (int i = 0; i < 30; i++) { 27 | try { 28 | System.out.printf("fib(%d) = %d\n", i, demo.fib(i)); 29 | Thread.sleep(100); 30 | } catch (RPCException e) { 31 | i--; // retry 32 | } 33 | } 34 | for (int i = 0; i < 30; i++) { 35 | try { 36 | ExpResponse res = demo.exp(2, i); 37 | Thread.sleep(100); 38 | System.out.printf("exp2(%d) = %d cost=%dns\n", i, res.getValue(), res.getCostInNanos()); 39 | } catch (RPCException e) { 40 | i--; // retry 41 | } 42 | } 43 | client.close(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/demo/DemoServer.java: -------------------------------------------------------------------------------- 1 | package rpckids.demo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import io.netty.channel.ChannelHandlerContext; 7 | import rpckids.common.IMessageHandler; 8 | import rpckids.common.MessageOutput; 9 | import rpckids.server.RPCServer; 10 | 11 | class FibRequestHandler implements IMessageHandler { 12 | 13 | private List fibs = new ArrayList<>(); 14 | 15 | { 16 | fibs.add(1L); // fib(0) = 1 17 | fibs.add(1L); // fib(1) = 1 18 | } 19 | 20 | @Override 21 | public void handle(ChannelHandlerContext ctx, String requestId, Integer n) { 22 | for (int i = fibs.size(); i < n + 1; i++) { 23 | long value = fibs.get(i - 2) + fibs.get(i - 1); 24 | fibs.add(value); 25 | } 26 | ctx.writeAndFlush(new MessageOutput(requestId, "fib_res", fibs.get(n))); 27 | } 28 | 29 | } 30 | 31 | class ExpRequestHandler implements IMessageHandler { 32 | 33 | @Override 34 | public void handle(ChannelHandlerContext ctx, String requestId, ExpRequest message) { 35 | int base = message.getBase(); 36 | int exp = message.getExp(); 37 | long start = System.nanoTime(); 38 | long res = 1; 39 | for (int i = 0; i < exp; i++) { 40 | res *= base; 41 | } 42 | long cost = System.nanoTime() - start; 43 | ctx.writeAndFlush(new MessageOutput(requestId, "exp_res", new ExpResponse(res, cost))); 44 | } 45 | 46 | } 47 | 48 | public class DemoServer { 49 | 50 | public static void main(String[] args) { 51 | RPCServer server = new RPCServer("localhost", 8888, 2, 16); 52 | server.service("fib", Integer.class, new FibRequestHandler()).service("exp", ExpRequest.class, 53 | new ExpRequestHandler()); 54 | server.start(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/demo/ExpRequest.java: -------------------------------------------------------------------------------- 1 | package rpckids.demo; 2 | 3 | public class ExpRequest { 4 | private int base; 5 | private int exp; 6 | 7 | public ExpRequest() { 8 | } 9 | 10 | public ExpRequest(int base, int exp) { 11 | this.base = base; 12 | this.exp = exp; 13 | } 14 | 15 | public int getBase() { 16 | return base; 17 | } 18 | 19 | public void setBase(int base) { 20 | this.base = base; 21 | } 22 | 23 | public int getExp() { 24 | return exp; 25 | } 26 | 27 | public void setExp(int exp) { 28 | this.exp = exp; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/demo/ExpResponse.java: -------------------------------------------------------------------------------- 1 | package rpckids.demo; 2 | 3 | public class ExpResponse { 4 | 5 | private long value; 6 | private long costInNanos; 7 | 8 | public ExpResponse() { 9 | } 10 | 11 | public ExpResponse(long value, long costInNanos) { 12 | this.value = value; 13 | this.costInNanos = costInNanos; 14 | } 15 | 16 | public long getValue() { 17 | return value; 18 | } 19 | 20 | public void setValue(long value) { 21 | this.value = value; 22 | } 23 | 24 | public long getCostInNanos() { 25 | return costInNanos; 26 | } 27 | 28 | public void setCostInNanos(long costInNanos) { 29 | this.costInNanos = costInNanos; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/server/DefaultHandler.java: -------------------------------------------------------------------------------- 1 | package rpckids.server; 2 | 3 | 4 | 5 | import io.netty.channel.ChannelHandlerContext; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import rpckids.common.IMessageHandler; 9 | import rpckids.common.MessageInput; 10 | 11 | public class DefaultHandler implements IMessageHandler { 12 | 13 | private final static Logger LOG = LoggerFactory.getLogger(DefaultHandler.class); 14 | 15 | @Override 16 | public void handle(ChannelHandlerContext ctx, String requesetId, MessageInput input) { 17 | LOG.error("unrecognized message type {} comes", input.getType()); 18 | ctx.close(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/server/MessageCollector.java: -------------------------------------------------------------------------------- 1 | package rpckids.server; 2 | 3 | import java.util.concurrent.ArrayBlockingQueue; 4 | import java.util.concurrent.BlockingQueue; 5 | import java.util.concurrent.ThreadFactory; 6 | import java.util.concurrent.ThreadPoolExecutor; 7 | import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy; 8 | import java.util.concurrent.TimeUnit; 9 | import java.util.concurrent.atomic.AtomicInteger; 10 | 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import io.netty.channel.ChannelHandler.Sharable; 15 | import io.netty.channel.ChannelHandlerContext; 16 | import io.netty.channel.ChannelInboundHandlerAdapter; 17 | import rpckids.common.IMessageHandler; 18 | import rpckids.common.MessageHandlers; 19 | import rpckids.common.MessageInput; 20 | import rpckids.common.MessageRegistry; 21 | 22 | @Sharable 23 | public class MessageCollector extends ChannelInboundHandlerAdapter { 24 | 25 | private final static Logger LOG = LoggerFactory.getLogger(MessageCollector.class); 26 | 27 | private ThreadPoolExecutor executor; 28 | private MessageHandlers handlers; 29 | private MessageRegistry registry; 30 | 31 | public MessageCollector(MessageHandlers handlers, MessageRegistry registry, int workerThreads) { 32 | BlockingQueue queue = new ArrayBlockingQueue<>(1000); 33 | ThreadFactory factory = new ThreadFactory() { 34 | 35 | AtomicInteger seq = new AtomicInteger(); 36 | 37 | @Override 38 | public Thread newThread(Runnable r) { 39 | Thread t = new Thread(r); 40 | t.setName("rpc-" + seq.getAndIncrement()); 41 | return t; 42 | } 43 | 44 | }; 45 | this.executor = new ThreadPoolExecutor(1, workerThreads, 30, TimeUnit.SECONDS, queue, factory, 46 | new CallerRunsPolicy()); 47 | this.handlers = handlers; 48 | this.registry = registry; 49 | } 50 | 51 | public void closeGracefully() { 52 | this.executor.shutdown(); 53 | try { 54 | this.executor.awaitTermination(10, TimeUnit.SECONDS); 55 | } catch (InterruptedException e) { 56 | } 57 | this.executor.shutdownNow(); 58 | } 59 | 60 | @Override 61 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 62 | LOG.debug("connection comes"); 63 | } 64 | 65 | @Override 66 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 67 | LOG.debug("connection leaves"); 68 | } 69 | 70 | @Override 71 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 72 | if (msg instanceof MessageInput) { 73 | this.executor.execute(() -> { 74 | this.handleMessage(ctx, (MessageInput) msg); 75 | }); 76 | } 77 | } 78 | 79 | private void handleMessage(ChannelHandlerContext ctx, MessageInput input) { 80 | // 业务逻辑在这里 81 | Class clazz = registry.get(input.getType()); 82 | if (clazz == null) { 83 | handlers.defaultHandler().handle(ctx, input.getRequestId(), input); 84 | return; 85 | } 86 | Object o = input.getPayload(clazz); 87 | @SuppressWarnings("unchecked") 88 | IMessageHandler handler = (IMessageHandler) handlers.get(input.getType()); 89 | if (handler != null) { 90 | handler.handle(ctx, input.getRequestId(), o); 91 | } else { 92 | handlers.defaultHandler().handle(ctx, input.getRequestId(), input); 93 | } 94 | } 95 | 96 | @Override 97 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 98 | LOG.warn("connection error", cause); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/java/rpckids/server/RPCServer.java: -------------------------------------------------------------------------------- 1 | package rpckids.server; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import io.netty.bootstrap.ServerBootstrap; 7 | import io.netty.channel.Channel; 8 | import io.netty.channel.ChannelInitializer; 9 | import io.netty.channel.ChannelOption; 10 | import io.netty.channel.ChannelPipeline; 11 | import io.netty.channel.EventLoopGroup; 12 | import io.netty.channel.nio.NioEventLoopGroup; 13 | import io.netty.channel.socket.SocketChannel; 14 | import io.netty.channel.socket.nio.NioServerSocketChannel; 15 | import io.netty.handler.timeout.ReadTimeoutHandler; 16 | import rpckids.common.IMessageHandler; 17 | import rpckids.common.MessageDecoder; 18 | import rpckids.common.MessageEncoder; 19 | import rpckids.common.MessageHandlers; 20 | import rpckids.common.MessageRegistry; 21 | 22 | public class RPCServer { 23 | 24 | private final static Logger LOG = LoggerFactory.getLogger(RPCServer.class); 25 | 26 | private String ip; 27 | private int port; 28 | private int ioThreads; 29 | private int workerThreads; 30 | private MessageHandlers handlers = new MessageHandlers(); 31 | private MessageRegistry registry = new MessageRegistry(); 32 | 33 | { 34 | handlers.defaultHandler(new DefaultHandler()); 35 | } 36 | 37 | public RPCServer(String ip, int port, int ioThreads, int workerThreads) { 38 | this.ip = ip; 39 | this.port = port; 40 | this.ioThreads = ioThreads; 41 | this.workerThreads = workerThreads; 42 | } 43 | 44 | private ServerBootstrap bootstrap; 45 | private EventLoopGroup group; 46 | private MessageCollector collector; 47 | private Channel serverChannel; 48 | 49 | public RPCServer service(String type, Class reqClass, IMessageHandler handler) { 50 | registry.register(type, reqClass); 51 | handlers.register(type, handler); 52 | return this; 53 | } 54 | 55 | public void start() { 56 | bootstrap = new ServerBootstrap(); 57 | group = new NioEventLoopGroup(ioThreads); 58 | bootstrap.group(group); 59 | collector = new MessageCollector(handlers, registry, workerThreads); 60 | MessageEncoder encoder = new MessageEncoder(); 61 | bootstrap.channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer() { 62 | @Override 63 | public void initChannel(SocketChannel ch) throws Exception { 64 | ChannelPipeline pipe = ch.pipeline(); 65 | pipe.addLast(new ReadTimeoutHandler(60)); 66 | pipe.addLast(new MessageDecoder()); 67 | pipe.addLast(encoder); 68 | pipe.addLast(collector); 69 | } 70 | }); 71 | bootstrap.option(ChannelOption.SO_BACKLOG, 100).option(ChannelOption.SO_REUSEADDR, true) 72 | .option(ChannelOption.TCP_NODELAY, true).childOption(ChannelOption.SO_KEEPALIVE, true); 73 | serverChannel = bootstrap.bind(this.ip, this.port).channel(); 74 | LOG.warn("server started @ {}:{}\n", ip, port); 75 | } 76 | 77 | public void stop() { 78 | // 先关闭服务端套件字 79 | serverChannel.close(); 80 | // 再斩断消息来源,停止io线程池 81 | group.shutdownGracefully(); 82 | // 最后停止业务线程 83 | collector.closeGracefully(); 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /NettyDemo/rpckids-master/src/rpc/rpc.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /SpringMVC/SpringMVC.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 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 | -------------------------------------------------------------------------------- /SpringMVC/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | com.test 9 | SpringMVC 10 | 1.0-SNAPSHOT 11 | 12 | 13 | 14 | org.springframework 15 | spring-web 16 | 4.1.2.RELEASE 17 | compile 18 | 19 | 20 | org.springframework 21 | spring-webmvc 22 | 4.1.2.RELEASE 23 | compile 24 | 25 | 26 | -------------------------------------------------------------------------------- /SpringMVC/web/WEB-INF/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /SpringMVC/web/WEB-INF/dispatcher-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 36 | 37 | 38 | text/plain;charset=UTF-8 39 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | application/json;charset=UTF-8 48 | text/html;charset=UTF-8 49 | 50 | 51 | 52 | 53 | 54 | QuoteFieldNames 55 | WriteDateUseDateFormat 56 | 57 | 58 | 59 | 60 | 62 | 63 | 64 | 65 | 66 | text/xml;charset=UTF-8 67 | application/xml;charset=UTF-8 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /SpringMVC/web/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | contextConfigLocation 8 | /WEB-INF/applicationContext.xml 9 | 10 | 11 | org.springframework.web.context.ContextLoaderListener 12 | 13 | 14 | dispatcher 15 | org.springframework.web.servlet.DispatcherServlet 16 | 17 | contextConfigLocation 18 | /WEB-INF/dispatcher-servlet.xml 19 | 20 | 1 21 | 22 | 23 | dispatcher 24 | / 25 | 26 | -------------------------------------------------------------------------------- /parent/.idea/artifacts/parent_war.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/../parent/target 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /parent/.idea/artifacts/parent_war_exploded.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/../parent/target/parent 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /parent/.idea/artifacts/son2_war.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/../parent/son2/target 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /parent/.idea/artifacts/son2_war_exploded.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/../parent/son2/target/parent 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /parent/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /parent/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /parent/.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__c3p0_c3p0_0_9_1_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__com_alibaba_druid_1_1_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__commons_logging_commons_logging_1_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__junit_junit_4_11.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__junit_junit_4_12.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__mysql_mysql_connector_java_6_0_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_mockito_mockito_core_1_10_19.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_mybatis_mybatis_3_4_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_mybatis_mybatis_spring_1_2_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_objenesis_objenesis_2_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_springframework_spring_aop_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_springframework_spring_beans_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_springframework_spring_context_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_springframework_spring_core_4_1_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_springframework_spring_core_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_springframework_spring_expression_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_springframework_spring_jdbc_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_springframework_spring_test_4_1_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/libraries/Maven__org_springframework_spring_tx_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /parent/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /parent/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /parent/jdbc/jdbc.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 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 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /parent/jdbc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 23 | 24 | parent 25 | com.test.maven 26 | 1.0-SNAPSHOT 27 | 28 | 29 | 4.0.0 30 | war 31 | 32 | son2 33 | son2 34 | 35 | 36 | 37 | 38 | org.mortbay.jetty 39 | maven-jetty-plugin 40 | 6.1.7 41 | 42 | 43 | 44 | 8888 45 | 30000 46 | 47 | 48 | ${project.build.directory}/${pom.artifactId}-${pom.version} 49 | 50 | / 51 | 52 | 53 | 54 | 55 | 56 | 57 | 62 | 63 | junit 64 | junit 65 | 4.11 66 | test 67 | 68 | 69 | 70 | com.alibaba 71 | druid 72 | 1.1.5 73 | 74 | 75 | org.springframework 76 | spring-test 77 | 4.1.4.RELEASE 78 | test 79 | 80 | 81 | org.mockito 82 | mockito-core 83 | 1.10.19 84 | test 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /parent/jdbc/src/main/java/DaoTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by 周杰伦 on 2018/6/7. 3 | */ 4 | public class DaoTest { 5 | } 6 | -------------------------------------------------------------------------------- /parent/jdbc/src/main/java/dao/UserInfoDAO.java: -------------------------------------------------------------------------------- 1 | package dao; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | public class UserInfoDAO { 7 | } 8 | -------------------------------------------------------------------------------- /parent/jdbc/src/main/java/entity/UserInfoBean.java: -------------------------------------------------------------------------------- 1 | package entity; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | public class UserInfoBean { 7 | } 8 | -------------------------------------------------------------------------------- /parent/jdbc/src/main/resources/h2/schema.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h2pl/MyTech/3173c26c2aa44dfb33d2c40e0aa50ba065b5eb63/parent/jdbc/src/main/resources/h2/schema.sql -------------------------------------------------------------------------------- /parent/jdbc/src/main/resources/mybatis/mapper/UserMapper.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h2pl/MyTech/3173c26c2aa44dfb33d2c40e0aa50ba065b5eb63/parent/jdbc/src/main/resources/mybatis/mapper/UserMapper.xml -------------------------------------------------------------------------------- /parent/jdbc/src/main/resources/test-data-source.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 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 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /parent/jdbc/src/main/resources/test-h2-applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /parent/jdbc/src/main/webapp/WEB-INF/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 28 | 29 | 30 | 31 | 32 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /parent/jdbc/src/main/webapp/WEB-INF/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /parent/jdbc/src/test/java/UserInfoDAOTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by 周杰伦 on 2018/6/7. 3 | */ 4 | import dao.UserInfoDAO; 5 | import entity.UserInfoBean; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.test.context.ContextConfiguration; 9 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 10 | 11 | import java.util.Date; 12 | import javax.annotation.Resource; 13 | import static org.junit.Assert.*; 14 | 15 | /** 16 | * 作用: 17 | * User: duqi 18 | * Date: 2017/6/24 19 | * Time: 09:33 20 | */ 21 | @RunWith(SpringJUnit4ClassRunner.class) 22 | @ContextConfiguration("classpath:test-h2-applicationContext.xml") 23 | public class UserInfoDAOTest { 24 | 25 | @Resource 26 | // private UserInfoDAO userInfoDAO; 27 | 28 | @Test 29 | public void saveUserInfoBean() throws Exception { 30 | // UserInfoBean userInfoBean = new UserInfoBean(); 31 | // userInfoBean.setUserId(1003L); 32 | // userInfoBean.setNickname("wangwu"); 33 | // userInfoBean.setMobile("18890987675"); 34 | // userInfoBean.setSex(1); 35 | // userInfoBean.setUpdateTime(new Date()); 36 | // userInfoBean.setCreateTime(new Date()); 37 | 38 | // int rows = userInfoDAO.saveUserInfoBean(userInfoBean); 39 | // 40 | // assertEquals(1, rows); 41 | } 42 | 43 | @Test 44 | public void updateUserInfoBean() throws Exception { 45 | } 46 | 47 | @Test 48 | public void getUserInfoBeanByUserId() throws Exception { 49 | } 50 | 51 | @Test 52 | public void getUserInfoBeanByMobile() throws Exception { 53 | } 54 | 55 | @Test 56 | public void listUserInfoBeanByUserIds() throws Exception { 57 | } 58 | 59 | @Test 60 | public void removeUserInfoBeanByUserId() throws Exception { 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /parent/jdbc/src/test/java/UserInfoManagerImplTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by 周杰伦 on 2018/6/7. 3 | */ 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.Mock; 9 | import org.mockito.MockitoAnnotations; 10 | import org.mockito.runners.MockitoJUnitRunner; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | import static org.mockito.Mockito.*; 15 | 16 | /** 17 | * 作用: 18 | * User: duqi 19 | * Date: 2017/6/24 20 | * Time: 09:55 21 | */ 22 | @RunWith(MockitoJUnitRunner.class) 23 | public class UserInfoManagerImplTest { 24 | 25 | // @Mock //用于定义被Mock的组件 26 | // private UserInfoDAO userInfoDAO; 27 | // 28 | // @InjectMocks //用于定义待测试的组件 29 | // private UserInfoManager userInfoManager = new UserInfoManagerImpl(); 30 | // 31 | // private UserInfo userInfoToSave; 32 | 33 | // @Before 34 | // public void setUp() throws Exception { 35 | // //用于初始化@Mock注解修饰的组件 36 | // MockitoAnnotations.initMocks(this); 37 | // 38 | // userInfoToSave = new UserInfo(); 39 | // userInfoToSave.setMobile("18978760099"); 40 | // userInfoToSave.setUserId(7777L); 41 | // userInfoToSave.setSex(1); 42 | // } 43 | // 44 | // @Test 45 | // public void saveUserInfo_case1() throws Exception { 46 | // //step1 准备数据和动作 47 | // doReturn(1).when(userInfoDAO).saveUserInfoBean(any(UserInfoBean.class)); 48 | // 49 | // //step2 运行待测试模块 50 | // Boolean res = userInfoManager.saveUserInfo(userInfoToSave); 51 | // 52 | // //step3 验证测试结果 53 | // assertTrue(res); 54 | // } 55 | // 56 | // @Test 57 | // public void saveUserInfo_case2() throws Exception { 58 | // //step1 准备数据和动作 59 | // doReturn(0).when(userInfoDAO).saveUserInfoBean(any(UserInfoBean.class)); 60 | // 61 | // //step2 运行待测试模块 62 | // Boolean res = userInfoManager.saveUserInfo(userInfoToSave); 63 | // 64 | // //step3 验证测试结果 65 | // assertFalse(res); 66 | // } 67 | 68 | @Test 69 | public void updateUserInfo() throws Exception { 70 | } 71 | 72 | @Test 73 | public void getUserInfoByUserId() throws Exception { 74 | } 75 | 76 | @Test 77 | public void getUserInfoByMobile() throws Exception { 78 | } 79 | 80 | @Test 81 | public void listUserInfoByUserIds() throws Exception { 82 | } 83 | 84 | @Test 85 | public void removeUserInfoByUserId() throws Exception { 86 | } 87 | 88 | } -------------------------------------------------------------------------------- /parent/log4j/log4j.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 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 | -------------------------------------------------------------------------------- /parent/log4j/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | parent 7 | com.test.maven 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | son1 13 | war 14 | 15 | son1 Maven Webapp 16 | 17 | http://www.example.com 18 | 19 | 20 | UTF-8 21 | 1.7 22 | 1.7 23 | 24 | 25 | 26 | 27 | 28 | log4j 29 | log4j 30 | 1.2.14 31 | 32 | 33 | 34 | 35 | 36 | 37 | son1 38 | 39 | 40 | 41 | maven-clean-plugin 42 | 3.0.0 43 | 44 | 45 | 46 | maven-resources-plugin 47 | 3.0.2 48 | 49 | 50 | maven-compiler-plugin 51 | 3.7.0 52 | 53 | 54 | maven-surefire-plugin 55 | 2.20.1 56 | 57 | 58 | maven-war-plugin 59 | 3.2.0 60 | 61 | 62 | maven-install-plugin 63 | 2.5.2 64 | 65 | 66 | maven-deploy-plugin 67 | 2.8.2 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /parent/log4j/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | Archetype Created Web Application 7 | 8 | -------------------------------------------------------------------------------- /parent/log4j/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Hello World!

4 | 5 | 6 | -------------------------------------------------------------------------------- /parent/parent.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 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 | -------------------------------------------------------------------------------- /parent/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | com.test.maven 8 | parent 9 | 1.0-SNAPSHOT 10 | war 11 | 12 | parent Maven Webapp 13 | 14 | http://www.example.com 15 | 16 | 17 | UTF-8 18 | 1.7 19 | 1.7 20 | 21 | 22 | 23 | 24 | 25 | org.springframework 26 | spring-context 27 | 4.1.7.RELEASE 28 | 29 | 30 | 31 | mysql 32 | mysql-connector-java 33 | 6.0.6 34 | 35 | 36 | 37 | c3p0 38 | c3p0 39 | 0.9.1.2 40 | 41 | 42 | 43 | org.springframework 44 | spring-jdbc 45 | 4.1.7.RELEASE 46 | 47 | 48 | junit 49 | junit 50 | 4.12 51 | 52 | 53 | 54 | org.mybatis 55 | mybatis 56 | 3.4.1 57 | 58 | 59 | 60 | org.mybatis 61 | mybatis-spring 62 | 1.2.2 63 | 64 | 65 | 66 | 67 | 68 | parent 69 | 70 | 71 | 72 | maven-clean-plugin 73 | 3.0.0 74 | 75 | 76 | 77 | maven-resources-plugin 78 | 3.0.2 79 | 80 | 81 | maven-compiler-plugin 82 | 3.7.0 83 | 84 | 85 | maven-surefire-plugin 86 | 2.20.1 87 | 88 | 89 | maven-war-plugin 90 | 3.2.0 91 | 92 | 93 | maven-install-plugin 94 | 2.5.2 95 | 96 | 97 | maven-deploy-plugin 98 | 2.8.2 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /parent/src/main/java/Department.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by 周杰伦 on 2018/6/7. 3 | */ 4 | public class Department { 5 | int id; 6 | String deptName; 7 | @Override 8 | public String toString() { 9 | return "Department [id=" + id + ", deptName=" + deptName + "]"; 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /parent/src/main/java/Employee.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by 周杰伦 on 2018/6/7. 3 | */ 4 | public class Employee { 5 | int id; 6 | String lastName; 7 | String email; 8 | Department department; 9 | @Override 10 | public String toString() { 11 | return "Employee [id=" + id + ", lastName=" + lastName + ", email=" 12 | + email + ", department=" + department + "]"; 13 | } 14 | public int getId() { 15 | return id; 16 | } 17 | public void setId(int id) { 18 | this.id = id; 19 | } 20 | public String getLastName() { 21 | return lastName; 22 | } 23 | public void setLastName(String lastName) { 24 | this.lastName = lastName; 25 | } 26 | public String getEmail() { 27 | return email; 28 | } 29 | public void setEmail(String email) { 30 | this.email = email; 31 | } 32 | public Department getDepartment() { 33 | return department; 34 | } 35 | public void setDepartment(Department department) { 36 | this.department = department; 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /parent/src/main/java/Student.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by 周杰伦 on 2018/6/7. 3 | */ 4 | public class Student { 5 | private String Id; 6 | private String Name; 7 | private String Sex; 8 | private String Age; 9 | 10 | Student(String Name, String Sex, String Age) { 11 | this.Id = null; //default 12 | this.Name = Name; 13 | this.Sex = Sex; 14 | this.Age = Age; 15 | } 16 | 17 | public String getId() { 18 | return Id; 19 | } 20 | 21 | public void setId(String Id) { 22 | this.Id = Id; 23 | } 24 | 25 | public String getName() { 26 | return Name; 27 | } 28 | 29 | public void setName(String Name) { 30 | this.Name = Name; 31 | } 32 | 33 | public String getSex() { 34 | return Sex; 35 | } 36 | 37 | public void setSex(String Sex) { 38 | this.Sex = Sex; 39 | } 40 | 41 | public String getAge() { 42 | return Age; 43 | } 44 | 45 | public void setage(String Age) { 46 | this.Age = Age; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /parent/src/main/java/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package dao; 2 | 3 | 4 | import entity.User; 5 | import org.springframework.jdbc.core.JdbcTemplate; 6 | 7 | /** 8 | * Created by 周杰伦 on 2018/6/7. 9 | */ 10 | 11 | 12 | public class UserDao { 13 | 14 | private JdbcTemplate jdbcTemplate; 15 | 16 | public JdbcTemplate getJdbcTemplate() { 17 | return jdbcTemplate; 18 | } 19 | 20 | public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { 21 | this.jdbcTemplate = jdbcTemplate; 22 | } 23 | 24 | public void addUser(User user) { 25 | 26 | String sql = "insert into user (username, password) values (?, ?)"; 27 | 28 | jdbcTemplate.update(sql, user.getUsername(), user.getPassword()); 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /parent/src/main/java/entity/User.java: -------------------------------------------------------------------------------- 1 | package entity; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | public class User { 7 | private String username; 8 | private String password; 9 | 10 | public String getUsername() { 11 | return username; 12 | } 13 | 14 | public void setUsername(String username) { 15 | this.username = username; 16 | } 17 | 18 | public String getPassword() { 19 | return password; 20 | } 21 | 22 | public void setPassword(String password) { 23 | this.password = password; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /parent/src/main/java/jdbcTemplate.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by 周杰伦 on 2018/6/7. 3 | */ 4 | 5 | import org.junit.Test; 6 | import org.springframework.jdbc.core.JdbcTemplate; 7 | import org.springframework.jdbc.datasource.DriverManagerDataSource; 8 | public class jdbcTemplate { 9 | 10 | @Test 11 | public void test1() { 12 | 13 | // JDBC模板依赖于连接池来获得数据的连接,所以必须先要构造连接池 14 | DriverManagerDataSource dataSource = new DriverManagerDataSource(); 15 | dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 16 | dataSource.setUrl("jdbc:mysql://localhost:3306/test"); 17 | dataSource.setUsername("root"); 18 | dataSource.setPassword("1234"); 19 | 20 | // 创建JDBC模板 21 | JdbcTemplate jdbcTemplate = new JdbcTemplate(); 22 | // 这里也可以使用构造方法 23 | jdbcTemplate.setDataSource(dataSource); 24 | 25 | // sql语句 26 | String sql = "select count(*) from user"; 27 | Long num = (long) jdbcTemplate.queryForObject(sql, Long.class); 28 | 29 | System.out.println(num); 30 | 31 | } 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /parent/src/main/java/jdbcTest.java: -------------------------------------------------------------------------------- 1 | import java.sql.*; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | public class jdbcTest { 7 | public static void main(String args[]) { 8 | jdbcTest.getAll(); 9 | jdbcTest.insert(new Student("Achilles", "Male", "14")); 10 | jdbcTest.getAll(); 11 | jdbcTest.update(new Student("Bean", "", "7")); 12 | jdbcTest.delete("Achilles"); 13 | jdbcTest.getAll(); 14 | } 15 | 16 | private static Connection getConn() { 17 | String driver = "com.mysql.cj.jdbc.Driver"; 18 | String url = "jdbc:mysql://localhost:3306/test?serverTimezone=CTT&useUnicode=true&characterEncoding=utf8&useSSL=false"; 19 | String username = "root"; 20 | String password = "1234"; 21 | Connection conn = null; 22 | try { 23 | Class.forName(driver); //classLoader,加载对应驱动 24 | conn = (Connection) DriverManager.getConnection(url, username, password); 25 | } catch (ClassNotFoundException e) { 26 | e.printStackTrace(); 27 | } catch (SQLException e) { 28 | e.printStackTrace(); 29 | } 30 | return conn; 31 | } 32 | private static int insert(Student student) { 33 | Connection conn = getConn(); 34 | int i = 0; 35 | String sql = "insert into students (Name,Sex,Age) values(?,?,?)"; 36 | PreparedStatement pstmt; 37 | try { 38 | pstmt = (PreparedStatement) conn.prepareStatement(sql); 39 | pstmt.setString(1, student.getName()); 40 | pstmt.setString(2, student.getSex()); 41 | pstmt.setString(3, student.getAge()); 42 | i = pstmt.executeUpdate(); 43 | pstmt.close(); 44 | conn.close(); 45 | } catch (SQLException e) { 46 | e.printStackTrace(); 47 | } 48 | return i; 49 | } 50 | 51 | private static int update(Student student) { 52 | Connection conn = getConn(); 53 | int i = 0; 54 | String sql = "update students set Age='" + student.getAge() + "' where Name='" + student.getName() + "'"; 55 | PreparedStatement pstmt; 56 | try { 57 | pstmt = (PreparedStatement) conn.prepareStatement(sql); 58 | i = pstmt.executeUpdate(); 59 | System.out.println("resutl: " + i); 60 | pstmt.close(); 61 | conn.close(); 62 | } catch (SQLException e) { 63 | e.printStackTrace(); 64 | } 65 | return i; 66 | } 67 | 68 | private static Integer getAll() { 69 | Connection conn = getConn(); 70 | String sql = "select * from students"; 71 | PreparedStatement pstmt; 72 | try { 73 | pstmt = (PreparedStatement)conn.prepareStatement(sql); 74 | ResultSet rs = pstmt.executeQuery(); 75 | int col = rs.getMetaData().getColumnCount(); 76 | System.out.println("============================"); 77 | while (rs.next()) { 78 | for (int i = 1; i <= col; i++) { 79 | System.out.print(rs.getString(i) + "\t"); 80 | if ((i == 2) && (rs.getString(i).length() < 8)) { 81 | System.out.print("\t"); 82 | } 83 | } 84 | System.out.println(""); 85 | } 86 | System.out.println("============================"); 87 | } catch (SQLException e) { 88 | e.printStackTrace(); 89 | } 90 | return null; 91 | } 92 | 93 | private static int delete(String name) { 94 | Connection conn = getConn(); 95 | int i = 0; 96 | String sql = "delete from students where Name='" + name + "'"; 97 | PreparedStatement pstmt; 98 | try { 99 | pstmt = (PreparedStatement) conn.prepareStatement(sql); 100 | i = pstmt.executeUpdate(); 101 | System.out.println("resutl: " + i); 102 | pstmt.close(); 103 | conn.close(); 104 | } catch (SQLException e) { 105 | e.printStackTrace(); 106 | } 107 | return i; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /parent/src/main/java/test/TestJDBCtemplate.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/7. 5 | */ 6 | import entity.User; 7 | import org.junit.Test; 8 | import org.springframework.context.ApplicationContext; 9 | import org.springframework.context.support.ClassPathXmlApplicationContext; 10 | import org.springframework.jdbc.core.JdbcTemplate; 11 | 12 | public class TestJDBCtemplate { 13 | 14 | 15 | 16 | public class TestJDBCTemplate { 17 | 18 | @Test 19 | public void test2() { 20 | 21 | ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml"); 22 | // UserService userService = (UserService) ctx.getBean("userService"); 23 | 24 | User user = new User(); 25 | user.setPassword("111"); 26 | user.setUsername("小王"); 27 | 28 | JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate"); 29 | } 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /parent/src/main/resources/jdbc.properties: -------------------------------------------------------------------------------- 1 | user=root 2 | password=123 3 | driverClass=com.mysql.jdbc.Driver 4 | jdbcUrl=jdbc:mysql:///spring 5 | 6 | initPoolSize=5 7 | maxPoolSize=10 -------------------------------------------------------------------------------- /parent/src/main/resources/spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 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 | -------------------------------------------------------------------------------- /parent/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | Archetype Created Web Application 7 | 8 | -------------------------------------------------------------------------------- /parent/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Hello World!

4 | 5 | 6 | -------------------------------------------------------------------------------- /parent/target/classes/Department.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h2pl/MyTech/3173c26c2aa44dfb33d2c40e0aa50ba065b5eb63/parent/target/classes/Department.class -------------------------------------------------------------------------------- /parent/target/classes/Employee.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h2pl/MyTech/3173c26c2aa44dfb33d2c40e0aa50ba065b5eb63/parent/target/classes/Employee.class -------------------------------------------------------------------------------- /parent/target/classes/Student.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h2pl/MyTech/3173c26c2aa44dfb33d2c40e0aa50ba065b5eb63/parent/target/classes/Student.class -------------------------------------------------------------------------------- /parent/target/classes/jdbc.properties: -------------------------------------------------------------------------------- 1 | user=root 2 | password=123 3 | driverClass=com.mysql.jdbc.Driver 4 | jdbcUrl=jdbc:mysql:///spring 5 | 6 | initPoolSize=5 7 | maxPoolSize=10 -------------------------------------------------------------------------------- /parent/target/classes/jdbcTemplate.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h2pl/MyTech/3173c26c2aa44dfb33d2c40e0aa50ba065b5eb63/parent/target/classes/jdbcTemplate.class -------------------------------------------------------------------------------- /parent/target/classes/jdbcTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h2pl/MyTech/3173c26c2aa44dfb33d2c40e0aa50ba065b5eb63/parent/target/classes/jdbcTest.class -------------------------------------------------------------------------------- /parent/target/classes/spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 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 | -------------------------------------------------------------------------------- /rabbitmq/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.test 8 | rabbitmq 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 14 | com.rabbitmq 15 | amqp-client 16 | 5.0.0 17 | 18 | 19 | com.rabbitmq 20 | amqp-client 21 | 4.1.0 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /rabbitmq/rabbitmq.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /rabbitmq/src/main/java/MsgReceiver.java: -------------------------------------------------------------------------------- 1 | import com.rabbitmq.client.Channel; 2 | import com.rabbitmq.client.Connection; 3 | import com.rabbitmq.client.ConnectionFactory; 4 | import com.rabbitmq.client.QueueingConsumer; 5 | 6 | import java.io.IOException; 7 | import java.util.concurrent.TimeoutException; 8 | 9 | /** 10 | * Created by 周杰伦 on 2018/6/22. 11 | */ 12 | public class MsgReceiver { 13 | private final static String QUEUE_NAME = "hello"; 14 | 15 | public static void main(String[] argv) throws IOException, InterruptedException, TimeoutException { 16 | ConnectionFactory factory = new ConnectionFactory(); 17 | factory.setHost("127.0.0.1"); 18 | // 打开连接和创建频道,与发送端一样 19 | Connection connection = factory.newConnection(); 20 | Channel channel = connection.createChannel(); 21 | 22 | // 声明队列,主要为了防止消息接收者先运行此程序,队列还不存在时创建队列。 23 | channel.queueDeclare(QUEUE_NAME, false, false, false, null); 24 | // 创建队列消费者 25 | QueueingConsumer consumer = new QueueingConsumer(channel); 26 | System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); 27 | // 指定消费队列 28 | channel.basicConsume(QUEUE_NAME, true, consumer); 29 | while (true) { 30 | // nextDelivery是一个阻塞方法(内部实现其实是阻塞队列的take方法) 31 | QueueingConsumer.Delivery delivery = consumer.nextDelivery(); 32 | String message = new String(delivery.getBody()); 33 | System.out.println(" [x] Received '" + message + "'"); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /rabbitmq/src/main/java/MsgSender.java: -------------------------------------------------------------------------------- 1 | import com.rabbitmq.client.Channel; 2 | import com.rabbitmq.client.Connection; 3 | import com.rabbitmq.client.ConnectionFactory; 4 | 5 | import java.io.IOException; 6 | import java.util.concurrent.TimeoutException; 7 | 8 | /** 9 | * Created by 周杰伦 on 2018/6/22. 10 | */ 11 | public class MsgSender { 12 | private final static String QUEUE_NAME = "hello"; 13 | 14 | public static void main(String[] args) throws IOException, TimeoutException { 15 | /** 16 | * 创建连接连接到MabbitMQ 17 | */ 18 | ConnectionFactory factory = new ConnectionFactory(); 19 | // 设置MabbitMQ所在主机ip或者主机名 20 | factory.setHost("127.0.0.1"); 21 | // 创建一个连接 22 | Connection connection = factory.newConnection(); 23 | // 创建一个频道 24 | Channel channel = connection.createChannel(); 25 | // 指定一个队列 26 | channel.queueDeclare(QUEUE_NAME, false, false, false, null); 27 | // 发送的消息 28 | String message = "hello world!龙轩"; 29 | // 往队列中发出一条消息 30 | channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); 31 | System.out.println(" [x] Sent '" + message + "'"); 32 | // 关闭频道和连接 33 | channel.close(); 34 | connection.close(); 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/com/JavaWeb/Servlet/Filter.java: -------------------------------------------------------------------------------- 1 | package com.JavaWeb.Servlet; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/6. 5 | */ 6 | public class Filter { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/JavaWeb/Servlet/Listener.java: -------------------------------------------------------------------------------- 1 | package com.JavaWeb.Servlet; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/6. 5 | */ 6 | public class Listener { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/JavaWeb/Servlet/Servlet实践.java: -------------------------------------------------------------------------------- 1 | package com.JavaWeb.Servlet; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.ServletRequest; 5 | import javax.servlet.ServletResponse; 6 | import javax.servlet.http.HttpServlet; 7 | import java.io.IOException; 8 | 9 | /** 10 | * Created by 周杰伦 on 2018/6/6. 11 | */ 12 | public class Servlet实践 extends HttpServlet{ 13 | @Override 14 | public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { 15 | res.setContentType("text/html;charset=UTF-8"); 16 | res.getWriter().write("abc"); 17 | res.getWriter().flush(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/Java集合/ArrayList和Vector和Stack.java: -------------------------------------------------------------------------------- 1 | package com.Java集合; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | import java.util.Vector; 9 | 10 | /** 11 | * Created by 周杰伦 on 2018/5/8. 12 | */ 13 | public class ArrayList和Vector和Stack { 14 | public static void main(String[] args) { 15 | //一般讨论集合类无非就是。这里的两种数组类型更是如此 16 | // 1底层数据结构 17 | // 2增删改查方式 18 | // 3线程安全与否 19 | // 4初始容量,扩容方式,扩容时机。 20 | // 5是否允许空,是否允许重复,是否有序 21 | 22 | ArrayList list = new ArrayList(); 23 | Vector vector = new Vector(); 24 | Stack stack = new Stack(); 25 | } 26 | 27 | @Test 28 | public void testArr() { 29 | ArrayList list = new ArrayList<>(); 30 | Object obj = new Object(); 31 | list.add(obj); 32 | list.add(0, new Object()); 33 | System.out.println(list.size()); 34 | //remove可以针对下标或者对象 35 | list.remove(obj); 36 | //set必须设置存在的下标 37 | list.set(0, obj); 38 | System.out.println(list.size()); 39 | System.out.println(list.get(0)); 40 | 41 | // 2 42 | // 1 43 | // java.lang.Object@3d8c7aca 44 | 45 | //modcount 46 | new Thread(new Runnable() { 47 | @Override 48 | public void run() { 49 | while (true) { 50 | list.add(0, obj); 51 | } 52 | } 53 | }).start(); 54 | while (true) { 55 | for (Object o : list) { 56 | System.out.println(o); 57 | } 58 | } 59 | // 抛出异常,使用迭代器时如果有其他线程进行了结构性修改,则抛出该异常 60 | // java.util.ConcurrentModificationException 61 | // at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) 62 | // at java.util.ArrayList$Itr.next(ArrayList.java:851) 63 | 64 | } 65 | 66 | @Test 67 | public void testArr2() { 68 | ArrayList list = new ArrayList(Integer.MAX_VALUE); 69 | //这里只会显示实际元素 70 | System.out.println(list.size()); 71 | //堆内存不够,理论上容量大小可以到最大整数 72 | // Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit 73 | // at java.util.ArrayList.(ArrayList.java:152) 74 | 75 | //扩容方式是1.5被扩容,线程不安全。 76 | } 77 | 78 | @Test 79 | public void testVector() { 80 | Vector vector = new Vector(); 81 | System.out.println(vector.capacity()); 82 | System.out.println(vector.size()); 83 | //10 84 | //1 85 | for (int i = 0;i < 10;i ++) { 86 | vector.add(1); 87 | } 88 | System.out.println(vector.capacity()); 89 | System.out.println(vector.size()); 90 | //10 91 | //10 92 | vector.add(1); 93 | System.out.println(vector.capacity()); 94 | System.out.println(vector.size()); 95 | //两倍扩容。capcity为原来的两倍 96 | // 20 97 | // 11 98 | 99 | //线程安全 100 | 101 | } 102 | 103 | @Test 104 | public void testStack() { 105 | Stack stack = new Stack(); 106 | stack.push(1); 107 | System.out.println(stack.size()); 108 | System.out.println(stack.capacity()); 109 | //stack继承vector,所以方法也是类似 110 | stack.peek(); 111 | stack.pop(); 112 | for (int i = 0;i <= 10;i ++) { 113 | stack.add(i); 114 | } 115 | System.out.println(stack.size()); 116 | System.out.println(stack.capacity()); 117 | } 118 | //11 119 | //20 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/Spring/SpringMVC/test.java: -------------------------------------------------------------------------------- 1 | package com.Spring.SpringMVC; 2 | 3 | import org.springframework.web.servlet.DispatcherServlet; 4 | 5 | /** 6 | * Created by 周杰伦 on 2018/6/4. 7 | */ 8 | public class test { 9 | DispatcherServlet dispatcherServlet = new DispatcherServlet(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/jvm/内存泄漏与内存溢出/内存泄漏.java: -------------------------------------------------------------------------------- 1 | package com.jvm.内存泄漏与内存溢出; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.Vector; 6 | 7 | /** 8 | * Created by 周杰伦 on 2018/6/13. 9 | */ 10 | 11 | //常见内存泄漏 12 | public class 内存泄漏 { 13 | public static void main(String[] args) { 14 | int i = 0 ; 15 | while (true) { 16 | System.out.println(++i); 17 | } 18 | } 19 | 20 | @Test 21 | public void test1() { 22 | Vector vector = new Vector(); 23 | while (true) { 24 | Object o = new Object(); 25 | vector.add(o); 26 | o = null; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/jvm/内存泄漏与内存溢出/内存溢出.java: -------------------------------------------------------------------------------- 1 | package com.jvm.内存泄漏与内存溢出; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.cglib.proxy.Enhancer; 5 | import org.springframework.cglib.proxy.MethodInterceptor; 6 | import org.springframework.cglib.proxy.MethodProxy; 7 | 8 | import java.lang.reflect.InvocationHandler; 9 | import java.lang.reflect.Method; 10 | import java.lang.reflect.Proxy; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | /** 15 | * Created by 周杰伦 on 2018/6/13. 16 | */ 17 | public class 内存溢出 { 18 | //方法区内存溢出 19 | public static void main(String[] args) { 20 | int i = 0; 21 | // //注意设置栈方法区最大值,不然压根不溢出 22 | // while (true) { 23 | // Delegate delegate = new Delegate(); 24 | // class Handler implements InvocationHandler { 25 | // Object object; 26 | // 27 | // public Handler(Object o) { 28 | // this.object = o; 29 | // } 30 | // 31 | // @Override 32 | // public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 33 | // 34 | // method.invoke(object, args); 35 | // return null; 36 | // } 37 | // } 38 | // User delegate1 = (User) Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(), new Handler(delegate)); 39 | // delegate1.run(); 40 | // System.out.println(++i); 41 | // 42 | // } 43 | while (true) { 44 | Enhancer enhancer = new Enhancer(); 45 | enhancer.setSuperclass(Delegate.class); 46 | enhancer.setUseCache(false); 47 | enhancer.setCallback(new MethodInterceptor() { 48 | @Override 49 | public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 50 | System.out.println("before"); 51 | return methodProxy.invokeSuper(o, objects); 52 | } 53 | }); 54 | Delegate delegate = (Delegate) enhancer.create(); 55 | delegate.run(); 56 | System.out.println(++i); 57 | } 58 | } 59 | 60 | //1,6和以前会显示pergem space, 61 | //1.7 62 | //Caused by: java.lang.OutOfMemoryError: Metaspace 63 | // at java.lang.ClassLoader.defineClass1(Native Method) 64 | // at java.lang.ClassLoader.defineClass(ClassLoader.java:763) 65 | // ... 20 more 66 | 67 | //栈内存 68 | @Test 69 | public void test1() { 70 | while (true) { 71 | new Thread(new Runnable() { 72 | @Override 73 | public void run() { 74 | while (true) { 75 | System.out.println("run"); 76 | } 77 | } 78 | }).start(); 79 | } 80 | } 81 | 82 | //栈溢出 9723 83 | //9724 84 | // 9725 85 | // java.lang.StackOverflowError 86 | // at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691) 87 | 88 | int a = 0; 89 | @Test 90 | public void test11() { 91 | System.out.println(++a); 92 | test11(); 93 | } 94 | 95 | //堆内存 96 | @Test 97 | public void test2() { 98 | List list = new ArrayList(); 99 | while (true) { 100 | list.add(new Object()); 101 | } 102 | } 103 | // Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 104 | 105 | int i = 0; 106 | //常量池内存溢出,1.8常量池跑到元空间里了 107 | @Test 108 | public void test3() { 109 | 110 | List list = new ArrayList(); 111 | int i = 0; 112 | while (true) { 113 | list.add(String.valueOf(i++).intern()); 114 | } 115 | //Error occurred during initialization of VM 116 | // OutOfMemoryError: Metaspace 117 | 118 | 119 | } 120 | 121 | interface User{ 122 | void run(); 123 | } 124 | static class Delegate implements User{ 125 | 126 | @Override 127 | public void run() { 128 | System.out.println("run"); 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/com/jvm/四种引用/弱引用.java: -------------------------------------------------------------------------------- 1 | package com.jvm.四种引用; 2 | 3 | import java.lang.ref.WeakReference; 4 | 5 | /** 6 | * Created by 周杰伦 on 2018/6/13. 7 | */ 8 | public class 弱引用 { 9 | 10 | } 11 | class WeakReferenceTest { 12 | 13 | public static int M = 1024*1024; 14 | 15 | public static void printlnMemory(String tag){ 16 | Runtime runtime = Runtime.getRuntime(); 17 | int M = WeakReferenceTest.M; 18 | System.out.println("\n"+tag+":"); 19 | System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)"); 20 | } 21 | 22 | public static void main(String[] args){ 23 | WeakReferenceTest.printlnMemory("1.原可用内存和总内存"); 24 | 25 | //创建弱引用 26 | WeakReference weakRerference = new WeakReference(new byte[10*WeakReferenceTest.M]); 27 | WeakReferenceTest.printlnMemory("2.实例化10M的数组,并建立弱引用"); 28 | System.out.println("weakRerference.get() : "+weakRerference.get()); 29 | 30 | System.gc(); 31 | StrongReferenceTest.printlnMemory("3.GC后"); 32 | System.out.println("weakRerference.get() : "+weakRerference.get()); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/jvm/四种引用/强引用.java: -------------------------------------------------------------------------------- 1 | package com.jvm.四种引用; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/13. 5 | */ 6 | public class 强引用 { 7 | } 8 | class StrongReferenceTest { 9 | 10 | public static int M = 1024 * 1024; 11 | 12 | public static void printlnMemory(String tag) { 13 | Runtime runtime = Runtime.getRuntime(); 14 | int M = StrongReferenceTest.M; 15 | System.out.println("\n" + tag + ":"); 16 | System.out.println(runtime.freeMemory() / M + "M(free)/" + runtime.totalMemory() / M + "M(total)"); 17 | } 18 | 19 | public static void main(String[] args) { 20 | StrongReferenceTest.printlnMemory("1.原可用内存和总内存"); 21 | 22 | //实例化10M的数组并与strongReference建立强引用 23 | byte[] strongReference = new byte[10 * StrongReferenceTest.M]; 24 | StrongReferenceTest.printlnMemory("2.实例化10M的数组,并建立强引用"); 25 | System.out.println("strongReference : " + strongReference); 26 | 27 | System.gc(); 28 | StrongReferenceTest.printlnMemory("3.GC后"); 29 | System.out.println("strongReference : " + strongReference); 30 | 31 | //strongReference = null;后,强引用断开了 32 | strongReference = null; 33 | StrongReferenceTest.printlnMemory("4.强引用断开后"); 34 | System.out.println("strongReference : " + strongReference); 35 | 36 | System.gc(); 37 | StrongReferenceTest.printlnMemory("5.GC后"); 38 | System.out.println("strongReference : " + strongReference); 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/java/com/jvm/四种引用/虚引用.java: -------------------------------------------------------------------------------- 1 | package com.jvm.四种引用; 2 | 3 | import java.lang.ref.PhantomReference; 4 | import java.lang.ref.ReferenceQueue; 5 | 6 | /** 7 | * Created by 周杰伦 on 2018/6/13. 8 | */ 9 | public class 虚引用 { 10 | } 11 | class PhantomReferenceTest { 12 | 13 | public static int M = 1024*1024; 14 | 15 | public static void printlnMemory(String tag){ 16 | Runtime runtime = Runtime.getRuntime(); 17 | int M = PhantomReferenceTest.M; 18 | System.out.println("\n"+tag+":"); 19 | System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)"); 20 | } 21 | 22 | public static void main(String[] args) throws InterruptedException { 23 | 24 | PhantomReferenceTest.printlnMemory("1.原可用内存和总内存"); 25 | byte[] object = new byte[10*PhantomReferenceTest.M]; 26 | PhantomReferenceTest.printlnMemory("2.实例化10M的数组后"); 27 | 28 | //建立虚引用 29 | ReferenceQueue referenceQueue = new ReferenceQueue(); 30 | PhantomReference phantomReference = new PhantomReference(object,referenceQueue); 31 | 32 | PhantomReferenceTest.printlnMemory("3.建立虚引用后"); 33 | System.out.println("phantomReference : "+phantomReference); 34 | System.out.println("phantomReference.get() : "+phantomReference.get()); 35 | System.out.println("referenceQueue.poll() : "+referenceQueue.poll()); 36 | 37 | //断开byte[10*PhantomReferenceTest.M]的强引用 38 | object = null; 39 | PhantomReferenceTest.printlnMemory("4.执行object = null;强引用断开后"); 40 | 41 | System.gc(); 42 | PhantomReferenceTest.printlnMemory("5.GC后"); 43 | System.out.println("phantomReference : "+phantomReference); 44 | System.out.println("phantomReference.get() : "+phantomReference.get()); 45 | System.out.println("referenceQueue.poll() : "+referenceQueue.poll()); 46 | 47 | //断开虚引用 48 | phantomReference = null; 49 | System.gc(); 50 | PhantomReferenceTest.printlnMemory("6.断开虚引用后GC"); 51 | System.out.println("phantomReference : "+phantomReference); 52 | System.out.println("referenceQueue.poll() : "+referenceQueue.poll()); 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/java/com/jvm/四种引用/软引用.java: -------------------------------------------------------------------------------- 1 | package com.jvm.四种引用; 2 | 3 | import java.lang.ref.SoftReference; 4 | 5 | /** 6 | * Created by 周杰伦 on 2018/6/13. 7 | */ 8 | public class 软引用 { 9 | 10 | } 11 | class SoftReferenceTest { 12 | 13 | public static int M = 1024*1024; 14 | 15 | public static void printlnMemory(String tag){ 16 | Runtime runtime = Runtime.getRuntime(); 17 | int M = StrongReferenceTest.M; 18 | System.out.println("\n"+tag+":"); 19 | System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)"); 20 | } 21 | 22 | public static void main(String[] args){ 23 | SoftReferenceTest.printlnMemory("1.原可用内存和总内存"); 24 | 25 | //建立软引用 26 | SoftReference softRerference = new SoftReference(new byte[10*SoftReferenceTest.M]); 27 | SoftReferenceTest.printlnMemory("2.实例化10M的数组,并建立软引用"); 28 | System.out.println("softRerference.get() : "+softRerference.get()); 29 | 30 | System.gc(); 31 | SoftReferenceTest.printlnMemory("3.内存可用容量充足,GC后"); 32 | System.out.println("softRerference.get() : "+softRerference.get()); 33 | 34 | //实例化一个4M的数组,使内存不够用,并建立软引用 35 | //free=10M=4M+10M-4M,证明内存可用量不足时,GC后byte[10*m]被回收 36 | SoftReference softRerference2 = new SoftReference(new byte[4*SoftReferenceTest.M]); 37 | SoftReferenceTest.printlnMemory("4.实例化一个4M的数组后"); 38 | System.out.println("softRerference.get() : "+softRerference.get()); 39 | System.out.println("softRerference2.get() : "+softRerference2.get()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/jvm/类加载/MyClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.jvm.类加载; 2 | 3 | import java.io.*; 4 | 5 | /** 6 | * Created by 周杰伦 on 2018/6/8. 7 | */ 8 | public class MyClassLoader extends ClassLoader { 9 | 10 | private String root; 11 | 12 | protected Class findClass(String name) throws ClassNotFoundException { 13 | byte[] classData = loadClassData(name); 14 | if (classData == null) { 15 | throw new ClassNotFoundException(); 16 | } else { 17 | return defineClass(name, classData, 0, classData.length); 18 | } 19 | } 20 | 21 | private byte[] loadClassData(String className) { 22 | String fileName = root + File.separatorChar 23 | + className.replace('.', File.separatorChar) + ".class"; 24 | try { 25 | InputStream ins = new FileInputStream(fileName); 26 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 27 | int bufferSize = 1024; 28 | byte[] buffer = new byte[bufferSize]; 29 | int length = 0; 30 | while ((length = ins.read(buffer)) != -1) { 31 | baos.write(buffer, 0, length); 32 | } 33 | return baos.toByteArray(); 34 | } catch (IOException e) { 35 | e.printStackTrace(); 36 | } 37 | return null; 38 | } 39 | 40 | public String getRoot() { 41 | return root; 42 | } 43 | 44 | public void setRoot(String root) { 45 | this.root = root; 46 | } 47 | 48 | public static void main(String[] args) { 49 | 50 | MyClassLoader classLoader = new MyClassLoader(); 51 | classLoader.setRoot("E:\\temp"); 52 | 53 | Class testClass = null; 54 | try { 55 | //这里使用全限定名避免太多同名类重复 56 | testClass = classLoader.loadClass("com.happy.Test2"); 57 | Object object = testClass.newInstance(); 58 | System.out.println(object.getClass().getClassLoader()); 59 | } catch (ClassNotFoundException e) { 60 | e.printStackTrace(); 61 | } catch (InstantiationException e) { 62 | e.printStackTrace(); 63 | } catch (IllegalAccessException e) { 64 | e.printStackTrace(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/jvm/类加载/Test2.java: -------------------------------------------------------------------------------- 1 | package com.jvm.类加载; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/8. 5 | */ 6 | public class Test2 { 7 | static { 8 | System.out.println("静态初始化块执行了!"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/jvm/类加载/双亲委派模型.java: -------------------------------------------------------------------------------- 1 | package com.jvm.类加载; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/8. 5 | */ 6 | public class 双亲委派模型 { 7 | // public Class loadClass(String name)throws ClassNotFoundException { 8 | // return loadClass(name, false); 9 | // } 10 | 11 | // protected synchronized Class loadClass(String name, boolean resolve)throws ClassNotFoundException { 12 | // // 首先判断该类型是否已经被加载 13 | // Class c = findLoadedClass(name); 14 | // if (c == null) { 15 | // //如果没有被加载,就委托给父类加载或者委派给启动类加载器加载 16 | // try { 17 | // if (parent != null) { 18 | // //如果存在父类加载器,就委派给父类加载器加载 19 | // c = parent.loadClass(name, false); 20 | // } else { 21 | // //如果不存在父类加载器,就检查是否是由启动类加载器加载的类,通过调用本地方法native Class findBootstrapClass(String name) 22 | // c = findBootstrapClass0(name); 23 | // } 24 | // } catch (ClassNotFoundException e) { 25 | // // 如果父类加载器和启动类加载器都不能完成加载任务,才调用自身的加载功能 26 | // c = findClass(name); 27 | // } 28 | // } 29 | // if (resolve) { 30 | // resolveClass(c); 31 | // } 32 | // return c; 33 | // } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/jvm/类加载/类加载器.java: -------------------------------------------------------------------------------- 1 | package com.jvm.类加载; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/8. 5 | */ 6 | public class 类加载器 { 7 | public static void main(String[] args) { 8 | ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 9 | System.out.println(Thread.currentThread().getContextClassLoader()); 10 | System.out.println(classLoader.getParent()); 11 | System.out.println(classLoader.getParent().getParent()); 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/jvm/类加载/类加载方式.java: -------------------------------------------------------------------------------- 1 | package com.jvm.类加载; 2 | 3 | /** 4 | * Created by 周杰伦 on 2018/6/8. 5 | */ 6 | public class 类加载方式 { 7 | public static void main(String[] args) throws ClassNotFoundException { 8 | ClassLoader loader = 类加载方式.class.getClassLoader(); 9 | System.out.println(loader); 10 | //使用ClassLoader.loadClass()来加载类,不会执行初始化块 11 | loader.loadClass("com.jvm.类加载.Test2"); 12 | //使用Class.forName()来加载类,默认会执行初始化块 13 | Class.forName("com.jvm.类加载.Test2"); 14 | //使用Class.forName()来加载类,并指定ClassLoader,初始化时不执行静态块 15 | // Class.forName("Test2", false, loader); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/resource/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | wthfeng的mvc练习项目 8 | 9 | hello 10 | com.JavaWeb.Servlet.Servlet实践 11 | 1 12 | 13 | 14 | hello 15 | /hello 16 | 17 | -------------------------------------------------------------------------------- /static/test.js: -------------------------------------------------------------------------------- 1 | console.log("hello world"); --------------------------------------------------------------------------------