Spring
未读前言
谈到 Spring 框架,大家往往大谈特谈一些高大上的东西,比如 IoC 控制反转、DI 依赖注入、AOP 面向切面等等,但却忘记了最基本的一点。 Spring 的本质是一个 Bean 工厂(beanFactory)或者说 Bean 容器
它按照我们的要求,生产我们需要的各种各样的bean,提供给我们使用。只是在生产bean的过程中,需要解决bean之间的依赖问题,才引入了依赖注入(DI)这种技术。也就是说依赖注入是beanFactory生产bean时为了解决bean之间的依赖的一种技术而已。
为什么需要 Spring 框架来给我们提供这个 beanFactory 的功能呢?原因是一般我们认为是,可以将原来硬编码的依赖,通过 Spring 这个 beanFactory 这个工厂来注入依赖,也就是说原来只有依赖方和被依赖方,现在我们引入了第三方—— spring 这个 beanFactory,由它来解决bean之间的依赖问题,达到了松耦合的效果;
这个只是原因之一,还有一个更加重要的原因:在没有 spring 这个 beanFactory 之前,我们都是直接通过 new 来实例化各 ...
Spring
未读前言
在上一章节结束之后,我们其实已经完成了 IoC 和 AOP 的全部核心内容。但是现在还需要使用 Spring.xml 进行配置。思考思考我们平时最多是怎么用 Spring 完成信息配置的?一是注解,二是 property。
为了在核心逻辑上填充一些自动化的功能,所需要的知识有:
包的扫描注册
注解配置使用
占位符属性的填充
设计
为了可以简化 Bean 对象的配置,达到整个 Bean 对象的注册都是自动扫描的。最基本的元素包括:
扫描路径入口
XML 解析扫描信息
给需要扫描的 Bean 对象做注解标记
扫描 Class 对象摘取 Bean 注册的基本信息
组装 Bean 注册信息
注册 Bean 对象
除此之外再顺带解决一个配置中占位符属性的知识点,比如可以通过 ${token} 给 Bean 对象注入进去属性信息,那么这个操作需要用到 BeanFactoryPostProcessor,因为它可以处理 在所有的 BeanDefinition 加载完成后,实例化 Bean 对象之前,提供修改 BeanDefinition 属性的机制
结合 bean ...
Spring
未读Spring 为什么需要事件,可以用来干什么?
用来解耦代码。高内聚,低耦合的设计思想
可以用于处理日志监控和各种事件发布订阅的客制化定义
观察者模式
在开发中,有很多利用到解耦的场景,例如在注册事件完成后异步发送事件推送消息,用户下单后异步发送MQ消息给与用户后续业务的跟进情况,用户付完款后就可以发送货物派送进度,都是依靠事件订阅和发布以及MQ消息这样的组件,来处理系统之间的调用解耦,最终也通过解耦的方式来提升整体系统架构的稳定性和负载能力
其实解耦思想就是观察者模式的一种体现。当对象间存在一对多关系时,则适合使用观察者模式,它定义了对象之间的一种一对多依赖关系。当一个对象的状态改变时,所有依赖他,与他有关的对象都会得到通知并且自动更新。
观察者模式角色
Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
O ...
Spring
未读SpringMVC扩展点
DispatchServlet:
这是Spring MVC的核心控制器,负责处理所有的HTTP请求和响应。它根据请求的URL来决定调用哪个处理器(Controller中的方法),并最终返回响应给客户端。
它使用HandlerMapping来确定具体的请求应该由哪个处理器方法来处理。
HandlerMapping:
这个接口定义了如何将HTTP请求映射到处理器方法。RequestMappingHandlerMapping是HandlerMapping的一个实现,它使用注解(如@RequestMapping)来映射URL到具体的处理器方法。
HandlerAdapter:
这个接口定义了如何调用处理器方法。RequestMappingHandlerAdapter是HandlerAdapter的一个实现,它负责调用与@RequestMapping注解的URL匹配的处理器方法。
RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter:
这两个组件是Spring MVC中处理基于注 ...
Spring
未读🚀StopWatch 使用教程
🤔 什么是StopWatch?
Hey 大家好,我是 Shio👋。今天我们来学习一个Spring框架中的工具类StopWatch,StopWatch是一个简单的停止看门狗计时器,它可以帮助开发者测量代码的执行时间。这对于性能调优和监控应用性能非常有用。想象一下,你有一个复杂的业务逻辑,你想知道每一步操作需要多长时间来执行,StopWatch就是你的瑞士军刀。
首先我们要了解为什么我们会使用StopWatch? 我总结为两点:
方便易用的API
纳秒级别的准确性
当然除了API, 我还想讲一讲StopWatch准确性实现所用到的 System.nanoTime()方法, 以及为什么不用System.currentTimeMillis()
📏StopWatch准确性如何保障?
StopWatch 类在Spring框架中用于精确测量时间间隔,它之所以能够提供高精度的时间测量,很大程度上归功于其内部使用的 System.nanoTime() 方法。下面我们来详细探讨 System.nanoTime() 以及 StopWatch 为何因此而更准确。 ...
MySQL
未读MySQL中的枚举字段, 该用什么类型定义呢?
问题简述
在项目数据库表设计阶段, 我们常常会用到枚举字段
例如 性别, 状态等数量有限在业务有特殊含义的字段
在建表时常用的字段有如下三种:
tinyint
varchar
enum
当然也有创建Reference table利用外键来管理枚举类型, 本节暂不讨论
其中 tinyint用的最多, varchar其次
enum由于一些比较严重的缺陷所以用的最少
下面我们将简述三种类型各自的特点以及应用场景
类型特点分析
TINYINT
特点
容量小:tinyint 只占用 1 字节的存储空间,可以存储范围为 -128 到 127 的整数值。因此,在数量有限的枚举字段中,使用 tinyint 可以有效地节省存储空间。
整数表示:tinyint 存储的是整数值,而不是直接存储含义明确的字符或字符串。这样可以在查询和索引时更高效地处理,因为比较整数值的速度通常比比较字符或字符串值的速度更快
优点:
节省存储空间:相比于字符串类型的枚举,使用 tinyint 类型可以节省存储空间,特别是在包含大量枚举字段的表中,可以显著减少数据占用。
...
MySQL
未读MYSQL语句执行顺序
// 先复制一篇, 明天来改
一、sql执行顺序
from
join (内连接inner join = join,左外连接left outer join = left join 右外连接 right outer join = right join )
on
where
group by(开始使用select中的别名,后面的语句中都可以使用)
avg,sum…
having
select
distinct
order by
limit
从这个顺序中我们不难发现,所有的 查询语句都是从from开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入。
**第一步:**首先对from子句中的前两个表执行一个笛卡尔乘积,此时生成虚拟表 vt1(选择相对小的表做基础表)。
**第二步:**接下来便是应用on筛选器,on 中的逻辑表达式将应用到 vt1 中的各个行,筛选出满足on逻辑表达式的行,生成虚拟表 vt2 。
**第三步:**如果是outer join 那么这一步就将添加外部行,left outer jion 就把左 ...
🌱JVM系列 之 详解JVM 内存分区(线程不安全篇)
🚧🚧🚧 暂待施工🚧🚧🚧
堆
方法区
Java 虚拟机所管理的内存中最大的一块,Java 堆是所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。
Java 世界中“几乎”所有的对象都在堆中分配,但是,随着 JIT 编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所有的对象都分配到堆上也渐渐变得不那么“绝对”了。从 JDK 1.7 开始已经默认开启逃逸分析,如果某些方法中的对象引用没有被返回或者未被外面使用(也就是未逃逸出去),那么对象可以直接在栈上分配内存
Java 堆是垃圾收集器管理的主要区域,因此也被称作 GC 堆(Garbage Collected Heap)。从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老年代;再细致一点有:Eden、Survivor、Old 等空间。进一步划分的目的是更好地回收内存,或者更快地分配内存
🌱JVM系列 之 详解JVM内存分区(线程安全篇)
引言
👋 大家好,我是Shio!今天我们要深入探索Java虚拟机(JVM)如何通过内存区域划分和管理来支撑庞大的Java生态并简化开发流程。我们将聚焦于JVM的内存区域、线程间共享与隔离机制以及各个内存区域的具体功能。
一、 JVM内存区域概述
1️⃣ 内存区域与内存模型的区别
首先区分两个概念:内存区域是JVM对物理内存的实际划分;而内存模型更关注数据的可见性和一致性问题。JVM内存区域主要包括五大块:程序计数器、虚拟机栈、本地方法栈、堆和方法区。
2️⃣ 线程共享与线程独占
🔄 线程共享内存区域:堆和方法区存放所有线程都能访问的数据(如对象实例和类信息),在这些区域操作时要考虑线程安全。
👤 线程独占内存区域:程序计数器、虚拟机栈和本地方法栈为每个线程单独分配,用于保存当前执行路径和局部变量等信息,无需关心线程安全问题。
今天我们着重讲解线程安全的内存区域, 线程不安全的堆和方法区因为内容比较多, 我们放在下一节进行讲解
二、 JVM内存区域详细解析
1️⃣ 程序计数器
💻
程序计数器(Program Count ...
♻️JVM系列 之 垃圾回收梳理(终章)
🚧🚧🚧 暂待施工🚧🚧🚧