模拟解析Mapper接口
点此返回
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry (BeanDefinitionRegistry beanFactory) throws BeansException { try { //扫描 mapper 包下的资源(使用通配符解析器) PathMatchingResourcePatternResolver resolver = new PathMatchingReso ...
模拟实现@ComponentScan
点此返回
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758//模拟 @ComponentScan 注解的解析//1、让自定义类实现 BeanDefinitionRegistryPostProcessor 接口// 并重写 postProcessBeanFactory 方法public class ComponentScanPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override // context.refresh public void postProcessBeanFactory (ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { ...
defineClass源码
点此返回
123456789101112131415161718192021222324252627private Class<?> defineClass(String name, Resource res) throws IOException { long t0 = System.nanoTime(); int i = name.lastIndexOf('.'); URL url = res.getCodeSourceURL(); if (i != -1) { String pkgname = name.substring(0, i); // Check if package already loaded. Manifest man = res.getManifest(); definePackageInternal(pkgname, man, url); } // Now read the class bytes and de ...
findClass方法源码
点此返回
123456789101112131415161718192021222324252627282930protected Class<?> findClass(final String name) throws ClassNotFoundException{ final Class<?> result; try { result = AccessController.doPrivileged( new PrivilegedExceptionAction<Class<?>>() { public Class<?> run() throws ClassNotFoundException { String path = name.replace('.', '/').concat(".class"); ...
loadClass方法源码剖析
点此返回
1、先在当前加载器的缓存中*查找有无目标类,如果有,直接返回。*
2、判断当前加载器的父加载器是否为空 ,如果不为空,则调用 parent.loadClass(name, false) 接口进行加载
3、反之,如果当前加载器的父类加载器为空,则调用 findBootstrapClassOrNull(name) 接口,让引导类加载器进行加载
4、如果通过以上3条路径都没能成功加载,则调用 findClass(name) 接口进行加载。该接口最终会调用 java.lang.ClassLoader 接口的 defineClass 系列的native接口加载目标Java类。
双亲委派的模型就隐藏在这第2和第3步中
1234567891011121314151617181920212223242526272829303132333435363738protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { s ...
16-类的加载器
类加载的方式显示加载:代码中调用ClassLoader加载class对象,比如直接使用Class.forName(name)或this.getClass().getClassLoader().loadClass()加载class对象
隐式加载:不直接在代码中调用ClassLoader加载class对象,而是通过虚拟机自动加载到内存,比如加载某个类的class文件时,该类的class文件中引用了另外一个类的对象,此时额外引用的类将通过JVM自动加载到内存
类的唯一性对于任意一个类,都需要由加载它的类加载器和这个类本身一同确认其在java虚拟机中的唯一性。每一个类加载器,都拥有一个独立的类名称空间:比较两个类是否相等,只有在这两个类是由同一个类加载器加载的前提下才有意义。否则,即使这两个类源自同一个Class文件,被同一个虚拟机加载,只要加载他们的类加载器不同,那这两个类就必定不相等。
12345678910111213141516171819public static void main(String[] args) { String rootDir = &q ...
15-类的生命周期(详细)
概述从class文件到加载到内存中的类,到类卸载出内存为止,它的整个生命周期包括如下7个阶段
注意:基本数据类型由虚拟机预先定义,引用数据类型需要进行类的加载
程序使用类的过程
1、加载将类的.class文件中的二进制数据读取到内存中,存放在运行时数据区的方法区中,并在内存中创建一个Java类原型(类模板对象)
类模板对象:java类在JVM中的一个快照。JVM从字节码文件中解析出常量池、类字段、类方法等存储在类模板中,如此JVM就可以在运行期通过类模板获取java中的任意信息,能够对java类的成员变量进行遍历,也能对方法进行调用(反射机制基于这一基础)
加载的步骤1、通过类的全名,获取类的二进制数据流
2、解析类的二进制数据流为方法区内的数据结构(java类模型)
3、创建java.lang.Class类的实例(作为方法区这个类的各个数据的访问入口)
类模型与Class实例位置类模型的位置:加载的类在JVM中创建相应的类结构,类结构存储在方法区(1.8之前:永久代;1.8之后:元空间)
Class实例的位置: .class文件加载后,在堆中创建一个J ...
14-垃圾回收器
GC分类按线程数:分为串行垃圾回收器和并行垃圾回收器
按工作模式:分为并发式垃圾回收器和独占式垃圾回收器
按碎片处理方式:分为
1、压缩式垃圾回收器:在回收完成后,对存活对象进行压缩整理,清除回收后的碎片(再分配对象空间的使用:指针碰撞)
2、非压缩式垃圾回收器(再分配对象空间的使用:空闲列表)
按工作的内存区间:分为年轻代垃圾回收器和老年代垃圾回收器
GC性能指标吞吐量:运行用户代码·的时间占总运行时间的比例(总运行时间 = 程序运行时间 + 内存回收时间)
吞吐量优先,意味着在单位时间内,STW的时间最短
垃圾收集开销:吞吐量的补数,垃圾收集所用时间与总运行时间的比例
暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间(STW)
暂停时间优先,意味着尽可能让单次STW的时间最短
收集频率:相对于应用程序的执行,收集操作发生的频率
内存占用:Java堆区所占的内存大小
快速:一个对象从诞生到被回收所经历的时间
注意:现在的标准为在最大吞吐量优先的情况下,降低停顿时间
回收器概述新生代收集器:Serial GC、ParNew GC、Parallel Scavenge ...
13-垃圾回收
相关概述垃圾:运行程序中没有任何指针指向的对象。这个对象就是需要被回收的垃圾
GC的作用:释放没用的对象,清楚内存里的记录碎片,以便JVM可以将整理出来的内存分配给新的对象,没有GC就不能保证应用程序的正常进行
内存泄露:对象在程序运行期间无法被回收
java自动内存管理:降低内存泄漏和内存溢出的风险
GC的作用范围:方法区和堆区(重点)
分类:频繁收集Young区,较少收集Old区,基本不动Perm区(元空间)
相关算法注意:在GC执行垃圾回收之前,需要先区分出内存中哪些是存活的对象,哪些是死亡的对象,只有被标记为已经死亡的对象,GC才会在执行垃圾回收的时候,释放掉它的内存空间。当一个对象已经不再被任何存活的对象继续引用时,就可以宣判为死亡
标记阶段:引用计数算法对每个对象保留一个整型的引用计数器属性。用来记录对象被引用的情况
对于一个对象A,只要任何一个对象引用了A,则A的引用计数器就加1;当引用失效时,引用计数器就减1。只要对象A的引用计数器的值为0,即表示对象A不可能再被使用,可进行回收
优点:实现简单,垃圾对象便于辨识;判定效率高,回收没有延迟性
缺点:1、需要单独的 ...
5-nginx-负载均衡
Nginx八层负载均衡upstream指令该指令是用来定义一组服务器,它们可以是监听不同端口的服务器,并且也可以是同时监听TCP和Unix socket的服务器。
服务器可以指定不同的权重,默认为1
server指令该指令用来指定后端服务器的名称和一些参数,可以使用域名、IP、端口或者Unix socket
负载均衡案例
客户端发送请求,通过nginx进行负载均衡到各个服务器上(proxy_pass指令)
负载均衡状态代理服务器在负责均衡调度中的状态有以下几个:
1)down:将该服务器标记为永久不可用,该代理服务器不参与负载均衡
down状态一般会对需要停机维护的服务器进行设置
2)backup将该服务器标记为备份服务器,当主服务器不可用时,将用来传递请求
当正常访问时,因为此时9002已经作为了备份服务器,所以nginx只负载均衡到9003端口。
当9003端口不可用时,9002将传递请求,此时nginx负载均衡到9002端口
3)max_fails 和 fail_timeout
max_fails=number
设置允许请求代理服务器失败的次数, ...