<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[justuseit的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/justuseit</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; justuseit]]></copyright><item><title><![CDATA[springboot源码解析(四)]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/115124277</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/115124277</guid><author>justuseit</author><pubDate>Tue, 23 Mar 2021 16:35:57 +0800</pubDate><description><![CDATA[@TOC
一、综述
上一节分析了环境上下文准备整体逻辑逻辑，留下来了一个点就是SpringApplication发布ApplicationEnvironmentPreparedEvent事件，相关监听器收到事件执行响应，其中有一个监听器执行的逻辑很复杂，也很重要，它就是ConfigFileApplicationListener。
ConfigFileApplicationListener是我们springboot应用初始化外部配置然后加载到环境上下文对象里面来的核心逻辑。包括有名的appollo都是通过这个]]></description><category></category></item><item><title><![CDATA[springboot源码解析(三)]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/115083055</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/115083055</guid><author>justuseit</author><pubDate>Mon, 22 Mar 2021 16:59:25 +0800</pubDate><description><![CDATA[@TOC
内容
开场白
上一节中，分析了springboot监听器的初始化和调用的逻辑，本节接着上一节来分析，本节分析springboot环境上下文初始化源码。首先看看整体的run方法代码，看看环境初始化代码在哪个具体位置
public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicat]]></description><category></category></item><item><title><![CDATA[springboot源码解析(二)]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/114947906</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/114947906</guid><author>justuseit</author><pubDate>Wed, 17 Mar 2021 21:04:44 +0800</pubDate><description><![CDATA[内容
上一次分析了SpringApplication的静态run方法是先实例化自己本身，然后再调用实例方法run。实例自己本身已经在上一节中分析完成，本节就分析实例run方法
public ConfigurableApplicationContext run(String... args) {
		//开启并启动计时器
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext ]]></description><category></category></item><item><title><![CDATA[springboot源码解析（一）]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/114945623</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/114945623</guid><author>justuseit</author><pubDate>Wed, 17 Mar 2021 20:14:36 +0800</pubDate><description><![CDATA[这里写自定义目录标题springboot源码解析（一）总结
springboot源码解析（一）
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class SpringbootWebApp {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebApp.class, args);
 ]]></description><category></category></item><item><title><![CDATA[基于springboot2的springmvc执行流程（四）]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/114544338</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/114544338</guid><author>justuseit</author><pubDate>Mon, 08 Mar 2021 20:07:35 +0800</pubDate><description><![CDATA[基于springboot2的springmvc执行流程（四）开始总结
开始
上一节分析到springmvc把参数名称和参数值解析出来后通过反射执行controller得到返回值，接下来要做的就是根据拿到的返回值然后匹配对应的ReturnValueHandler来解析返回值，如下图：

今天就是要分析源码的点就是，如何匹配返回值处理器，返回值处理器是如何解析的，里面还有管内容协商的处理。
1、这里的属性returnValueHandlers是从哪里来的呢？
这个invokeAndHandle方法是在Servl]]></description><category></category></item><item><title><![CDATA[基于springboot2的springmvc执行流程（三）]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/114376773</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/114376773</guid><author>justuseit</author><pubDate>Thu, 04 Mar 2021 21:10:28 +0800</pubDate><description><![CDATA[基于springboot2的springmvc执行流程（三）总结
上一节我们分析了RequestMappingHandlerAdapter里面整体处理流程。核心的逻辑就是生成一个ServletInvocableHandlerMethod对象，用于真正的执行handle逻辑，handle的代码如下：

这个方法核心逻辑就两步，我都写了注释：
1、执行请求得到返回值
2、处理返回值
这一节我重点分析处理请求得到返回值的逻辑
进入到方法invokeForRequest

这个方法是在ServletInvocabl]]></description><category></category></item><item><title><![CDATA[基于springboot2的springmvc执行流程（二）]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/114334110</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/114334110</guid><author>justuseit</author><pubDate>Wed, 03 Mar 2021 21:04:41 +0800</pubDate><description><![CDATA[基于springboot2的springmvc执行流程（二）
上一节中，我们分析了springmvc的大致执行流程，把DispatherServlet里面的整体流程都分析了一遍，doDispatch方法里面有一行代码是整个流程最核心的逻辑，如下图：

接下来我们进入到RequestMappingHandlerAdapter的handle方法进行源码分析：
首先会进入RequestMappingHandlerAdapter的父类handle方法，handle方法是handlerAdapter的定级接口的方法，]]></description><category></category></item><item><title><![CDATA[基于springboot2的springmvc执行流程（一）]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/114333622</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/114333622</guid><author>justuseit</author><pubDate>Wed, 03 Mar 2021 20:31:29 +0800</pubDate><description><![CDATA[基于springboot2的springmvc执行流程（一）springmvc的详细流程图准备工作源码解析结语
springmvc的详细流程图

为了读源码，我们需要把源码下载下来，然后打断点，通过debug来分析原来的运行流程。下面我们就一起来分析源码。
准备工作
一、首先，创建一个最简单的springboot程序在pom文件里面加上
org.springframework.boot
spring-boot-starter-web

依赖，就有了springmvc的功能。
二、创建一个controller]]></description><category></category></item><item><title><![CDATA[spring bean 生命周期和bean的扩展点]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/102940250</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/102940250</guid><author>justuseit</author><pubDate>Thu, 07 Nov 2019 14:24:02 +0800</pubDate><description><![CDATA[理解spring bean 的生命周期，就能熟悉spring Ioc容器的初始化流程，就知道它有哪些扩展点，能给写框架或者业务都带来很多便利。
1、代码演示bean生命周期
public class SpringLifecycleDemo implements BeanFactoryPostProcessor, InstantiationAwareBeanPostProcessor, BeanPo...]]></description><category></category></item><item><title><![CDATA[一图看懂mybatis核心原理和执行流程]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/102783557</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/102783557</guid><author>justuseit</author><pubDate>Mon, 28 Oct 2019 16:36:22 +0800</pubDate><description><![CDATA[1、mybatis核心对象之间的依赖关系
(1)DefaultSessionFactory、confugration、DefaultSqlSession、Excutor、Transaction之间的包含关系

（2）(1)DefaultSessionFactory、confugration、DefaultSqlSession、Excutor、Transaction对象之间的依赖关系

2、myba...]]></description><category></category></item><item><title><![CDATA[EMQX broker安装与启动 以及启动中遇到的问题]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/102779949</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/102779949</guid><author>justuseit</author><pubDate>Mon, 28 Oct 2019 14:44:47 +0800</pubDate><description><![CDATA[1、先下载安装包
下载地址: https://www.emqx.io/downloads
最好下载zip包安装，rpm方式安装容易出现其他未知异常和不可预知的冲突。
根据自己操作系统版本选择对应安装包,我选择的是
emqx-centos6-v3.2.3.zip这个版本
2、把下载好的包放到特定目录，然后解压
$ unzip emqx-centos6-v3.2.3.zip
3、启动EMQX
进入em...]]></description><category></category></item><item><title><![CDATA[JDK动态代理原理和mybatis的Mapper底层实现]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/102665747</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/102665747</guid><author>justuseit</author><pubDate>Mon, 21 Oct 2019 18:12:56 +0800</pubDate><description><![CDATA[一、jdk动态代理原理
所谓动态代理就是代理对象是动态生成的，不像静态代理那样写好一个代理类，到时候直接new一个对象来代理就可以，静态代理当然没有动态代理灵活，扩展性也没有动态代理好，程序都讲究高内聚低耦合，所以动态代理相对于静态代理来说使用还是大很多。
其实JDK动态代理要做的事情用三句话就可以总结：
1、拦截目标对象
2、查找生成指定代理类
3、根据代理类的构造函数构造代理对象
所以我们后面...]]></description><category></category></item><item><title><![CDATA[StampedLock相对于ReentrantReadWriteLock性能提升的原理]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/102610151</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/102610151</guid><author>justuseit</author><pubDate>Fri, 18 Oct 2019 09:49:27 +0800</pubDate><description><![CDATA[StampedLock比ReentrantReadWriteLock性能更好，主要体现在以下几个方面：
1、增加乐观读功能，减少写线程饥饿现象出现
2、StampedLock要比ReentrantReadWriteLock消耗小
3、StampedLock增加了更多的无锁操作，使线程间阻塞减少到最小。
那么它为什么能做到这些呢？
主要实现的逻辑就是：
1、写状态每写一次增加一次值，可以通过比较两次...]]></description><category></category></item><item><title><![CDATA[jdk1.8中ConcurrentHashMap的并发原理]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/102521086</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/102521086</guid><author>justuseit</author><pubDate>Sat, 12 Oct 2019 18:20:40 +0800</pubDate><description><![CDATA[ConcurrentHashMap的并发原理
我们都知道jdk1.8之前ConcurrentHashMap是采用分段锁的机制允许多线程并发操作一个ConcurrentHashMap的方式来提高并发的，它的主要思想是优化HashTable中全局锁，让锁更加细粒度来达到更高的并发度的。
但是JDK1.8里面的ConcurrentHashMap则完全不一样，它用到了CAS思想，使用的是乐观锁思想，乐观锁...]]></description><category></category></item><item><title><![CDATA[关于ThreadLocal的几点误区]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/102498803</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/102498803</guid><author>justuseit</author><pubDate>Fri, 11 Oct 2019 12:28:00 +0800</pubDate><description><![CDATA[关于ThreadLocal的几点误区
我们都知道遇到线程安全问题时可以用ThreadLocal来解决。但是关于这个类，很多人都存在一些误区。
误区一：ThreadLocal就是一个map，key就是线程相关的参数，value就是要存放的数据。
误区二：一个线程对应一个ThreadLocal，重复设置值会被覆盖。
先看一个例子：
public class ThreadLocalTest {
    ...]]></description><category></category></item><item><title><![CDATA[HashMap源码解析]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/102487264</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/102487264</guid><author>justuseit</author><pubDate>Fri, 11 Oct 2019 11:24:14 +0800</pubDate><description><![CDATA[本文主要通过分析HashMap的各个字段的意义，常用方法的大致逻辑来大致了解HashMap的源码。
一、HashMap的主要字段
1、hashmap中有一个静态内部类Node，其结构并不复杂，下面情况它的代码：

static class Node&lt;K,V&gt; implements Map.Entry&lt;K,V&gt; {
        final int hash;
      ...]]></description><category></category></item><item><title><![CDATA[Java MQTT V3客户端使用实践]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/102390504</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/102390504</guid><author>justuseit</author><pubDate>Tue, 08 Oct 2019 18:23:49 +0800</pubDate><description><![CDATA[一、先通过一个测试Java MQTT 客户端是否支持多线程并发的实例大概看看如何使用：
生产者代码：
public class MqttClientPublish {

    private static AtomicInteger count = new AtomicInteger();
    private static int qos = 1;
    private static St...]]></description><category></category></item><item><title><![CDATA[spring基于注解的声明式事务原理分析]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/101680362</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/101680362</guid><author>justuseit</author><pubDate>Sun, 29 Sep 2019 11:51:09 +0800</pubDate><description><![CDATA[spring声明式事务管理jdbc数据源的流程和实现原理## 标题
首先我们要搞清楚两个核心问题：
1、spring声明式事务管理是基于springAOP的，是在目标方法上环绕执行事务逻辑。
2、对于jdbc事务管理是基于同一个连接的。也就是jdbc一个事物中所有的操作必须在同一个连接中完成。事务逻辑的大致伪代码如下：
Connection conn = DriverManager.getConn...]]></description><category></category></item><item><title><![CDATA[AbstractRoutingDataSource实现多数据源自动切换的原理分析]]></title><link>https://blog.youkuaiyun.com/justuseit/article/details/101210543</link><guid>https://blog.youkuaiyun.com/justuseit/article/details/101210543</guid><author>justuseit</author><pubDate>Mon, 23 Sep 2019 16:13:06 +0800</pubDate><description><![CDATA[一、先说怎么用AbstractRoutingDataSource配置多数据源自动切换
1、先配置多个数据源
@Configuration
@MapperScan(basePackages = “com.example.demo.mappers”, sqlSessionTemplateRef = “sqlSessionTemplate”)
public class MultiDataSourceCo...]]></description><category></category></item></channel></rss>