Spring Boot 打包成Jar包运行的原理
相比于传统的Java打包方式,使用SpringBoot打包插件打包成jar包后,可以直接使用java -jar 运行SpringBoot项目,本篇就来分析一下运行的原理。
SpringBoot打包插件
1234<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId></plugin>
打包完后会生成两个文件,一个***.jar和***.jar.original
.jar文件是SpringBoot打包后生成的文件,.jar.original是用原生方式打包生成的文件,对比一下两个的区别
.jar.original文件
.jar文件
.jar.original就是普通的jar打包的结构,这里主要看.jar文件的结构:
META-INFO目录:META-INFO/MANIFEST.MF里包含了jar包的元数据,包含了项目的启动类等信息.
org目录: ...
设计一个支持热加载的Java应用启动器
热加载是指在不重启服务的情况下使更改的代码生效。注意和热部署的区别,热加载主要是在开发环境下使用。
首先要知道Java程序是怎么运行起来的,Java类加载分为其7个阶段。
其中加载阶段是用户可以自定义,而验证阶段、准备阶段、解析阶段、初始化阶段都是用 JVM 来处理的。整个类加载是在Java 中一个叫做类加载器上进行的,如果我们能程序更改后,让程序所在的进程能够实时的获取到编译后的Class类字节码信息,然后重新加载的话,那么就可以实现热加载功能。
Java 类加载器类加载器,顾名思义就是加载Java类的工具,Java默认设置了三个类加载器。
BootstrapClassloader
ExtClassloader
AppClassloader
BootstrapClassloader 叫做启用类加载器,用于加载JRE核心类库,使用C++实现。加载路径%JAVA_HOME%/lib下的所有类库。
ExtClassloader 扩展类加载器,加载%JAVA_HOME%/lib/ext中的所有类库。
AppClassloader 应用类加载器也叫系统类加载器System C ...
聊一聊Tomcat 系统架构设计
总体架构Tomcat 是一个应用服务器,那么要开发一个应用服务器,首先捋一捋它的需求,要实现那些功能。
1、 首先可以和客户端建立连接,并且能够处理客户端的连接
2、 其次还要解析处理我们写的 Servlet
3、 最后能够根据客户端的请求找到相应的 Servlet。
在 Tomcat 中将这些需求分为了两大功能
处理 Socket 连接,并将网络字节流转换成 Request 对象和 Response 对象
解析、加载和管理 Servlet,处理请求并返回响应数据
Tomcat 将这两大功能,设计成了两个主要的组件
连接器(Connector)
容器(Container)
来看一下 Tomcat 的总体架构
上图中是 Tomcat 的整体架构,一个 Tomcat 代表一个 Server,一个 Server 下包含对个 Service,每个 Service 下包含多个连接器和一个容器。
Service 本身没有什么重要的作用,它只是把连接器和容器组装在一起了,但是 Tomcat 可以同时设置多个 Service,也就可以部署多个服务。比如有两个相同的项目,可以把这两个项目放到两 ...
Java泛型中的类型擦除以及Type接口
Java 泛型(generics)是JDK1.5中引入的一个新特性,其本质是参数化类型,解决不确定具体对象类型的问题;其所操作的数据类型被指定为一个参数(type parameter)这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
但是在Java中并不是真正的泛型,实际上是“伪泛型”
类型擦除(type Erasure)为了与之前的版本兼容,JDK1.5中通过类型擦除来增加的泛型功能。Java泛型只是在编译器层次上,在编译后生成的字节码中是不包含泛型中类型的信息的。通过一个例子来证明类型擦除
12345678public class main { public static void main(String[] args) { ArrayList<String> sList = new ArrayList<String>(); ArrayList<Integer> iList = new ArrayList<Integer>(); ...
Java函数式编程
简介什么是函数式编程函数式编程是一种编程范式,即一切都是数学函数。在Java面向对象编程中,程序是一系列相互作用(方法)的对象,而在函数式编程中,程序会是一个无状态的函数组合序列。
函数是“第一等公民”“第一等公民”指的是函数和其他数据类型一样,处于平等的地位。可以赋值给变量、可以作为另一个函数的参数或者作为一个函数的返回值。比如
12345// 将两数相加的逻辑赋值给变量sumvar sum = (a,b)->a+b;// 将函数作为另一个函数的参数operation(sum)
Java函数试编程Lambda 表达式历史上研究函数式编程的理论是Lambda演算,所以我们经常把支持函数式编程的编码风格称为Lambda表达式。
在Java中Lambda 表达式的表达形式:
1(参数)->方法体
参数:可以有多个,如果只有一个可以省略括号
->:箭头符号。
方法体:方法体超过一句时,要用{}包裹,可以根据情况看是否需要return语句
函数式接口Java 8提供了函数式编程接口的概念,用作Lambda表达式的类型。
函数式接口:只定义了单一抽象方法的接口 ...
HashMap那些事儿
HashMap 在 Java 中是一个使用高频的数据结构,JDK1.8 以后 HashMap 进行了一次翻天覆地的改变。
本文基于 JDK1.8 分析一下 HashMap
存储结构转换在 JDK1.8 以前 HashMap 采用的是数组+链表的结构,JDK1.8 以后又引入了红黑树的结构,会在链接和红黑树之间转换,结合源码分析一下 HashMap 对数组+链表和数组+红黑树的转换首先看一下数据的存储结构
1transient HashMap.Node<K, V>[] table;
HashMap 定义了一个 Node 的数组,Node 的定义
1234567 static class Node<K, V> implements Entry<K, V> { final int hash; final K key; V value; HashMap.Node<K, V> next; // ....省略}
Node 中包含了四个属性hash、key、value、next。 ...
TCP三次握手和四次挥手
定义:TCP(Transmission Control Protocol:传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议.
TCP在发送数据前,会在通信双方之间建立一条连接。通过这条连接,客户端和服务端可以保存一份对方的信息,如ip地址、端口号等。通信双方的数据传输就是在这条连接上进行的。这条连接的建立和断开的过程就是所谓的三次握手和四次挥手
TCP报文头部数据在了解三次握手和四次挥手之前,先来了解一下TCP报文的头部数据结构上图中有几个字段是在三次握手和四次挥手需要的
Sequence number(seq):序列号 32位
Acknowledgment number(ack): 确认序列号 32位
SYN、ACK、FIN标志位
SYN : 建立起一个新的连接
ACK : 确认号有效
FIN : 释放一个连接
注意: 不要将ack和ACK理解混了,ack是一串序列号,ACK是一个标志位。当ACK为1时,代表ack序列号有效
三次握手三次握手是TCP建立连接的过程。主要作用是判断通信双方有没有传输数据的能力。看一下整个握手的过程。
三次握手步骤:
第一 ...
Mybatis中mapper生成代理的过程
目录
mybatis中mapper代理的生成过程
与Spring集成时mapper代理的生成过程
与SpringBoot集成时mapper代理的生成过程
mybatis中mapper代理的生成过程构建代理类工厂从入口点开始一步一步看,首先SqlSessionFactoryBuilder类中build()方法加载配置文件
12345678910public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error ...
Java SPI机制
少侠你现在是否还这样连接数据库
123456try { Class.forName("com.mysql.jdbc.Driver"); Connection connection = DriverManager.getConnection("URL","root","password");} catch (Exception e) { e.printStackTrace();}
少侠你知道Class.forName()这句早已经没用了么?Java 官方已经把它优化掉了。想知道怎么优化的么?不要急,且看我慢慢道来。
SPISPI 全名:Service Provider Interface,是 JDK 内置的一种服务发现机制,可以将服务接口与服务发现分离以达到解耦的效果。可以提升程序的可扩展性。比如 jdbc 只提供了接口,具体的实现由各个运营商解决、经常用的 log 日志类LogFactory,还有阿里的 dubbo 更是将 SPI 运用的淋漓尽致。 ...
Mysql优化工具explain
explain的使用很简单,只要在select语句的前面加上explain的关键字就好了,来看个例子
先创建两个表,注意两个表的索引
12345678910111213141516171819202122232425262728293031CREATE TABLE `user` ( `id` varchar(32) NOT NULL, `name` varchar(32) DEFAULT NULL, `role` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO `user` VALUES ('1', '1', '1');INSERT INTO `user` VALUES ('10', '10', '5');INSERT INTO `user` VALUES ('2', '2', ...