_金欣
醉舞经阁半卷书,坐井说天阔。
展开
-
【SpringBoot3.0源码】启动流程源码解析 • 上
SpringBoot启动类:步入方法:这里分为两步:初始化步入SpringApplication的构造方法中:首先获取资源加载器、保存primarySources属性、web类型,设置初始化器和监听器,获取main方法所在的类重点看一下获取初始化器和监听器这部分。在此之前,看一下271行的代码:在SpringBoot的老版本中,是没有这快代码的,这里主要是提前加载一些初始化器、监听器和其他配置放入缓存中,以便后续获取。步入方法中:最终来到这里:这里首先构造一个加载器,再去调用load方法。步原创 2023-02-13 16:13:03 · 2339 阅读 · 71 评论 -
【SpringBoot3.0源码】自动装配源码解析
根据前面几章,我们对IOC源码的分析,应该不难理解:我们先去扫描指定的包下所有的@Component、@Configuration,以及配置类内的@Import、@Bean等。所谓自动装配,就是自动将第三方jar包的配置类注入到IOC容器中,常见的xxx-spring-boot-starter。自动装配应该是SpringBoot最有东西的标志,因为可以通过这种约定大于配置的设计,让编程变得简单,让工资变的更低,让java开发不在有门槛。既如此,我们可得知启动SpringBoot后,会将。原创 2023-02-07 12:52:17 · 1388 阅读 · 4 评论 -
【SpringBoot3.0源码】内置tomcat启动源码解析
又是这两个方法,我就不点进去看了,这一看不就是先去根据web服务工厂类型找beanName,底层应该还是遍历所有的beanDefination,在这里肯定就是SpringBoot自动装配,把相关的类已经封装成beanDefination了。也就是说,Tomcat服务器的启动带动了IOC容器的加载。前面谈到IOC的时候,讲过这个方法,这个refresh方法,使用了模版设计,可以提高代码复用性和扩展性。SpringBoot内置了Tomcat,那就是相反,IOC容器的加载,伴随着Tomcat服务的启动。原创 2023-02-07 01:39:59 · 1222 阅读 · 5 评论 -
【Spring6源码・MVC】请求处理流程源码解析
值得一提的是我们这个demo没有文件,也没有参数,所以撸流程还是很容易的,如果有参数还要注意是如何解析参数的,如果用@RequestParam注解的话,直接通过反射就可以获取到,Spring也提供了处理这个注解的解析器,如果不加注解,会默认使用名称绑定,底层用asm框架读取字节码来获取参数名称,所以编码记得用@RequestParam声明参数,之后会放进一个缓存数组中,在。我们知道,在IOC容器加载的同时,初始化了registry这个HashMap,这个HashMap中存放了请求路径和对应的方法。原创 2023-02-10 18:09:09 · 2053 阅读 · 72 评论 -
【Spring6源码・MVC】初始化registry,完成url和controller的映射关系
首先调用createRequestMappingInfo方法,获取方法上的数据,包括请求类型和请求路径,最后封装成RequestMappingInfo类。综上所述:再启动SpringBoot项目的时候,就已经解析了所有的请求路径和对应的请求方法,并且将他们封装进registry这个HashMap中。紧接着,依旧调用createRequestMappingInfo方法,上面那个参数是方法,那么就会解析方法上的请求类型和请求路径。之后就可以通过请求路径来找到对应的方法,然后去invoke方法。原创 2023-02-10 11:27:27 · 2063 阅读 · 70 评论 -
【Spring6源码・事务】事务核心源码解析
这里怪我了,我应该写两个sql操作的,但是流程太过繁琐,比如事务的隔离级别我并不能一一枚举出来,而且,我也没有写SpringBoot3的一些源码,就用SpringBoot环境来讲解,是有一些麻烦。这里会提交事务,当然在提交事务之前会判断这个是不是新事务,如果是新事务则会提交事务,如果不是新事务,则会保存当前事务,跳出当前事务后,执行新事务,一并提交。这里有两个核心步骤:第一个步骤是返回一个包含事务相关信息的事务状态,第二个步骤是将事务信息设置进线程本地变量。,我们知道事物的代理对象是如何创建的。原创 2023-02-06 17:12:33 · 1327 阅读 · 3 评论 -
【Spring6源码・事务】事务的代理对象的创建
其内部有个静态内部类,里面还有两个静态内部类,一个是JDK动态代理配置,一个是CgLib代理配置。那么问题来了,org.springframework.transaction.config.internalTransactionAdvisor对象又是在什么时候加载的呢?当然了,这只是冰山一角,SpringBoot3.0的坑,我给你们慢慢踩,你们慢慢看,哈哈哈哈哈。类,应该是被Spring6移除了,那这个时候就因应该看Mybatis有没有什么解决办法了。原创 2023-02-06 12:54:11 · 1048 阅读 · 3 评论 -
【Spring6源码・AOP】AOP源码解析
让我们看看是如何进行转换的,步入registry.getInterceptors方法,初始化拦截器集合,获取Advice【切面相关的配置】,对适配器进行循环,找到符合的拦截器,然后加入我们初始化好的拦截器List集合中,创建完代理对象之后,最终,会真正的执行我们的目标方法,但是步入该方法,会进入cglib代理类的拦截方法。调用after方法。不行了,我得去吃饭了,妈妈叫我吃饭了,呜呜呜,你们自己看看,挺简单的。好了,好了,累死了,好像有个问题没有写,就是三级缓存相关的,明天吧,专门给三级缓存写一篇。原创 2023-01-17 17:04:08 · 1392 阅读 · 3 评论 -
【Spring6源码・AOP】代理对象的创建
前几章bean实例化之后,我们对bean进行了属性填充,紧接着就会调用initializeBean()方法返回该bean的代理对象,如果不需要被代理,那么就会直接返回该bean。然后就是调用 createProxy 方法创建代理对象,这里做了一个判断,如果这个bean包含一些切面的配置,那么就会调用createProxy对bean创建代理。因为我们这里的bean是testImpl,所以,我们这里使用的是cglib代理。最终,会真正的执行我们的目标方法,但是步入该方法,会进入cglib代理类的拦截方法。原创 2023-01-16 09:34:36 · 531 阅读 · 0 评论 -
【Spring6源码・IOC】Bean的初始化 - 终结篇
上一篇,我们实例化了bean之后,将bean放入了第三级缓存,看一下这个addSingletonFactory方法,如果一级缓存中没有对应的bean,那么会将未初始化的bean放入三级缓存,会将bean提前暴露出来。我们来一起看一下这个处理属性的doWithLocalFields方法,首先通过getDeclaredFields方法获取类的属性集合,然后进行遍历调用函数去处理。这里主要有两点,一个是针对属性上的注解,一个是针对方法上的注解,大部分的时候会放在属性上,也有时候会放在方法上,比如set方法上。原创 2023-01-12 10:10:44 · 6625 阅读 · 185 评论 -
【Spring6源码・IOC】Bean的实例化
bean的实例化原创 2023-01-09 14:02:28 · 4052 阅读 · 7 评论 -
【Spring6源码・IOC】BeanDefinition的加载
环境:Spring6、SpringBoot3.0、JDK17多看注释梳理整体设计思想IOC是一个容器,对象的创建、使用和销毁都是由IOC容器来管理。《五分钟带你速通Spring IOC》加载配置文件(XML\YAML…)、配置类,并解析成BeanDefinitionBeanFactoryPostProcessor对BeanDefinition做一些处理实例化bean对象初始化bean对象(属性填充等),并且在初始化前后通过BeanPostProcessor对bean对象进行相关处理。原创 2023-01-06 05:27:27 · 7030 阅读 · 42 评论 -
你说反射有点难追,我觉得应该知难而退。
我们来好好看看这个方法,这个方法中是反射修改属性的核心方法,包括修改静态属性、final属性、volatile属性等。步入setInt()方法,注意这三个红色框框:一个是上面我们抛出的错误,这里主要是解包失败,类型没匹配成功。完结了,撒花,又浪费10分钟写文章,你们谁要是看到这里,就帮忙看看上面为什么修改属性类型之后不能设置值?它里面会有一下setXx、getXx方法,除了set()方法之外,其余都是抛出非法参数异常。jdk8:类型是可以转换成功,但是值设置不进去,具体原因不详,谁知道记得评论告诉我。原创 2023-02-01 17:29:36 · 2862 阅读 · 8 评论 -
Timer应用小案例补充----Notify、while相关
Java线程实现采用内核线程实现,线程的休眠及唤醒(状态切换)需借助操作系统进行,这是一个极其耗时耗力的操作。但若线程休眠及运行的时间都很短(例如毫秒/秒,文中案例就是一个典型案例),系统将频繁的对线程状态进行切换,导致严重的性能损耗,并对着循环次数的递增而放大。创建一个顾客线程(消费者):告知老板要的包子的种类和数量,调用wait方法,放弃cpu的执行,进入到WAITING状态(无限等待)在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。原创 2022-11-09 16:08:36 · 353 阅读 · 0 评论 -
阿光附体,浅谈Timer,源码分析。
说到Java的定时器,是不是想起了伟大的Timer,提起Timer是不是想起Netflix的Spring Cloud的注册中心Eureka,如果没记错,它内部定时发送心跳的的机制就是用Timer做的,不过后来的一些注册中心(比如Nacos)都用ScheduledExecutorService代替了,今天我们来浅谈一下这个Timer。进而start之后会执行TimerThread的run方法。我们来简单分析一下,从new Timer()开始。奥里给,奥里给,每天充满正能量!那么它又是怎么实现定时任务的呢?原创 2022-11-09 11:22:54 · 368 阅读 · 0 评论 -
写了一行“System.out.println()”代码,于是我被开除了
作为资深的cv工程师,想必大家都知道System.out.println()吧。看一下源码: /** * Prints a String and then terminate the line. This method behaves as * though it invokes <code>{@link #print(String)}</code> and then * <code>{@link #println()}</code>.原创 2022-10-12 02:00:15 · 428 阅读 · 0 评论 -
URLConnection的作用及其使用
URLConnection是一个抽象类,表示指向URL指定资源的活动连接。URLConnection有两个不同但相关的用途:URLConnection可以检查服务器发送的首部,并相应地做出响应。它可以设置客户端请求中使用的首部字段。最后URLConnection可以用POST、PUT和其他HTTP请求方法向服务器发回数据;URLConnection类是Java的协议处理器机制的一部分;原创 2022-09-29 18:19:03 · 389 阅读 · 0 评论 -
十四种锁作用及其使用
Java偏向锁(Biased Locking)是指它会偏向于第一个访问锁的线程,如果在运行过程中,只有一个线程访问加锁的资源,不存在多线程竞争的情况,那么线程是不需要重复获取锁的,这种情况下,就会给线程加一个偏向锁。如果线程并发进一步加剧,线程的自旋超过了一定次数,或者一个线程持有锁,一个线程在自旋,又来了第三个线程访问时(反正就是竞争继续加大了),轻量级锁就会膨胀为重量级锁,重量级锁会使除了此时拥有锁的线程以外的线程都阻塞。如果一个线程对数据加上共享锁后,那么其他线程只能对数据再加共享锁,不能加独占锁。原创 2022-08-25 16:28:50 · 279 阅读 · 2 评论 -
Lock作用及其使用
而非公平锁就是一种随机的分配,不关乎先后顺序,非公平锁会随机分配一个处于就绪状态的线程来获取锁并执行相应的逻辑。这种锁既然叫读写锁,表示也是两个锁,一个是读操作相关的,是共享锁;公平锁和非公平锁各有优劣,公平锁需要维护一个队列,需要知道各个线程进入就绪状态的顺序,而非公平锁则不需要,只需要每次随机分配一个已经处于就绪状态的线程即可。那么实际上,JDK同样考虑到这一点,提供了一种读写锁ReentrantReadWriteLock的支持,它可以限定读锁和写锁,在不同的锁下有不同的互斥效果。原创 2022-08-25 15:30:20 · 469 阅读 · 0 评论 -
synchronized使用
当然如果是一个线程 A 需要访问实例对象 obj1 的 synchronized 方法 f1(当前对象锁是obj1),另一个线程 B 需要访问实例对象 obj2 的 synchronized 方法 f2(当前对象锁是obj2),这样是允许的,因为两个实例对象锁并不同相同,此时如果两个线程操作数据并非共享的,线程安全是有保障的,遗憾的是如果两个线程操作的是共享数据,那么线程安全就有可能无法保证了。修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。原创 2022-08-25 00:06:28 · 210 阅读 · 0 评论 -
基于BlockingQueue的异步处理
不可插入为null的元素,入队和出队使用的是同一个锁。直到队列不满时,再进行入队操作。当出队时,队列为空,则调用notEmpty.await(),进入阻塞状态,直到队列不为空时,则出队。LinkedBlockingQueue允许两个线程同时在两端进行入队和出队操作,但一端同时只能有一个线程进行操作,是通过两个锁进行区分的。count只能在两个地方变化,一个是入队的方法(进行+1操作),另一个是出队的方法(进行-1操作),而AtomicInteger是原子安全的,所以也就确保了底层队列的数据同步。原创 2022-08-23 17:02:08 · 456 阅读 · 0 评论 -
RestTemplate源码解析
一句话概括RestTemplate,RestTemplate封装了原生的HttpURLConnection,采用Restful的理念,更优雅地来完成对HTTP服务的调用。原创 2022-08-11 17:04:44 · 679 阅读 · 3 评论 -
ThreadLocalRandom的作用及其使用
这里设计为了延迟初始化,另外变量 instance 是个 ThreadLocalRandom 的一个实例,该变量是 static 的,当多线程通过 ThreadLocalRandom 的 current 方法获取 ThreadLocalRandom 的实例时候其实获取的是同一个,但是由于具体的种子是存放到线程里面的,如果每个线程维护自己的一个种子变量,每个线程生成随机数时候根据自己老的种子计算新的种子,并使用新种子更新老的种子,然后根据新种子计算随机数,就不会存在竞争问题,这会大大提高并发性能。...原创 2022-08-11 15:32:56 · 635 阅读 · 0 评论 -
OkHttp的作用及其使用
OkHttp 是一套处理 HTTP 网络请求的依赖库,由 Square 公司设计研发并开源,目前可以在 Java 和 Kotlin 中使用。依赖。原创 2022-08-11 15:25:02 · 276 阅读 · 0 评论 -
httpclient作用及其使用
前几篇文章我们讲述了URLConnection,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性,它不仅使客户端发送Http请求变得容易,而且也方便开发人员测试接口(基于Http协议的),提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入。...原创 2022-08-11 14:58:15 · 543 阅读 · 0 评论 -
HttpURLConnection作用及其使用
HTTPURLConnection是URLConnection的抽象子类。它包含的方法可以获得和设置请求方法,确定是否重定向,获得响应码和消息,确定是否使用了代理服务器。常用API接口。原创 2022-08-11 12:08:04 · 321 阅读 · 0 评论 -
URLConnection的作用及其使用
URLConnection是一个抽象类,表示指向URL指定资源的活动连接。URLConnection可以检查服务器发送的首部,并相应地做出响应。它可以设置客户端请求中使用的首部字段。最后URLConnection可以用POST、PUT和其他HTTP请求方法向服务器发回数据;URLConnection类是Java的协议处理器机制的一部分;...原创 2022-08-11 11:54:29 · 933 阅读 · 1 评论 -
RestTemplate作用及其使用
在返回的 ResponseEntity 中,可以获取响应头中的信息,其中 getStatusCode 方法用来获取响应状态码, getBody 方法用来获取响应数据, getHeaders 方法用来获取响应头,在浏览器中访问该接口。去表示,第二个参数是接口返回的数据类型,最后是一个可变长度的参数,用来给占位符填值。getForObject 和 getForEntity 的差异主要体现在返回值上, getForObject 的返回值就是服务提供者返回的数据,使用 getForObject 无法获取到响应头。.原创 2022-08-10 16:43:30 · 757 阅读 · 2 评论 -
Java合并word文档的两种方式
Java合并word文档的两种方式。原创 2022-08-10 10:50:10 · 1609 阅读 · 1 评论 -
@RequestParam的作用及使用
RequestParam可以加在方法参数前}不加@RequestParam前端的参数名需要和后端控制器的变量名保持一致才能生效不加@RequestParam参数为非必传,加@RequestParam写法参数为必传。但@RequestParam可以通过@RequestParam(required = false)设置为非必传。@RequestParam可以通过@RequestParam(“param”)或者@RequestParam(value = “param”)指定传入的参数名。...原创 2022-08-10 10:31:17 · 715 阅读 · 0 评论 -
Spring源码之finishRefresh()
最后,我们会来到WebServerManager#start,在这里发布了Nacos服务注册的事件。我们重点跟进这个方法refreshContext(context);还记得我们的启动类么?原创 2022-08-04 15:43:53 · 340 阅读 · 4 评论 -
注解@EnableAutoConfiguration的作用以及如何使用
@EnableAutoConfiguration原创 2022-08-04 14:04:56 · 1131 阅读 · 1 评论 -
Java监听器的作用以及如何使用
Java监听器原创 2022-08-04 12:25:05 · 2079 阅读 · 0 评论 -
@Async注解的作用以及如何实现异步监听机制
使用@Async标注在方法上,可以使该方法异步的调用执行。而所有异步方法的实际执行是交给TaskExecutor的。在需要异步执行的类上标注@Async,比如,我们现在有一个需要监听的事件。如下方式会使@Async失效。......原创 2022-08-04 12:14:57 · 470 阅读 · 1 评论 -
@Import注解的作用以及如何使用
-原创 2022-08-04 11:25:58 · 618 阅读 · 1 评论 -
CAS自旋锁,看这一篇就够了
《最伟大的作品》让我们穿越到1920年,见到了马格利特的绿苹果、大利的超现实、常玉画的大腿、莫奈的睡莲、徐志摩的诗…他说“最伟大的作品”并不是自己的歌,而是这个世界上最伟大的艺术作品们。............原创 2022-07-07 08:43:32 · 3501 阅读 · 57 评论 -
Random类的那些事
上篇文章,我们讲解了生成随机数的几种方式。接下来,我们再仔细看看Random是如何实现的。原创 2022-07-06 12:02:32 · 281 阅读 · 5 评论 -
浅浅的谈一下ThreadLocalInsecureRandom
今天看了一眼随机数相关,无意间发现了这个类。这看起来真不错啊,有继承了SecurityRandom,又带有ThreadLocal字样,难道拥有了二者的特性,成为了结合体?我们来一探究竟。原创 2022-07-05 17:35:43 · 540 阅读 · 5 评论 -
SecureRandom那些事|真伪随机数
前面的几篇文章,介绍了随机数的几种生成方式,那么什么是伪随机数呢?所谓伪随机数,是指只要给定⼀个初始的种⼦,产⽣的随机数序列是完全⼀样的。原创 2022-07-05 17:24:14 · 363 阅读 · 0 评论 -
JVMRandom不可设置种子|问题追溯|源码追溯
上一篇文章,我们介绍了几种随机数的生成策略。那么接下来,我们来分析一下JVMRandom存在的问题。当我们如下正常构建一个随机数的时候,是没有任何问题的。原创 2022-07-05 15:13:33 · 407 阅读 · 0 评论