- 博客(42)
- 收藏
- 关注
原创 ReentrantReadWriteLock 源码分析
目录概述属性分析读锁的获取读锁的释放写锁的获取写锁的释放总结概述ReentrantReadWriteLock 也称作读写锁。读锁是共享的,多个线程可以同时获取到读锁;写锁是排他的,当一个线程获取到写锁,其它线程只能等待写锁被释放才能获取。且支持锁的降级,不支持锁的升级,也就是说一个线程获取到了写锁,则它还可以获取该线程的读锁;而一个线程获取到了读锁,不能再获取写锁。因为读锁是允许多个线程读的,如果多个持有读锁的线程都想要升级写锁,造成了互相等待,就会形成死锁,但是写锁降级成读锁确实可以的,因为获取写锁的
2021-06-27 14:55:44
274
原创 ThreadLocal 源码分析
目录概述ThreadLocalMap 中的 Entry 类ThreadLocalMap初始化 ThreadLocalMapThreadLocal 存储到 Entry 数组中的下标的计算方式ThreadLocal 的常用方法initialValue()withInitial()set()remove()get()扩容逻辑总结概述ThreadLocal 的作用是提供了一个线程局部变量,我们可以通过它的 get() / set() 方法来访问这个变量。不同线程间的这个变量是不同的,因此达到线程隔离的方式。提
2021-06-17 15:00:03
411
1
原创 注册 @RequestMapping 方法与 URL 的映射关系
目录内容总结注:SpringMVC 版本 5.2.15本文尝试从源码角度带大家看一下 SpringMVC 如何注册 Controller 与 URL 之间的对应关系。SpringMVC 中通过 HandlerMapping 定义了请求和处理程序对象之间的映射关系。首先我们看到 AbstractHandlerMethodMapping,它是实现了 HandlerMapping 接口的抽象基类。内容AbstractHandlerMethodMapping # afterPropertiesSetp
2021-05-25 20:38:52
737
2
原创 Tomcat 启动控制台打印乱码解决方案
在你的 Tomcat 安装目录的 conf 文件夹下有个 logging.properties 文件,添加或修改这一个配置项如:apache-tomcat-9.0.46\conf\logging.propertiesjava.util.logging.ConsoleHandler.encoding = GBK
2021-05-25 10:28:56
193
原创 @ResponseBody 注解原理
@ResponseBody 注解原理1. 介绍2. 作用范围3. 源码分析4. 总结注:SpringMVC 版本 5.2.151. 介绍@ResponseBody 注解的作用是将方法的返回值通过适当的转换器转换为指定的格式之后,写入到 response 对象的 body 区,通常用来返回 JSON、XML 数据。使用了 @ResponseBody 注解标记的方法不再做视图解析2. 作用范围标记在方法上标记在类上通过 @RestController 注解实现,此时所有的方法都将会被添
2021-05-24 17:08:22
3238
4
原创 @RequestParam 注解原理
@RequestParam 注解原理介绍源码分析介绍@RequestParam 注解用于绑定请求参数。它的具体内容如下:// 该注解作用的方法形参@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface RequestParam { /** * 要绑定的参数名 */ @AliasFor("name") String value() default "
2021-05-24 10:12:00
1784
6
原创 SpringMVC 执行流程解析
SpringMVC 执行流程解析1. ContextLoaderListener2. DispatcherServlet 初始化逻辑3. DispatcherServlet 处理流程注:SpringMVC 版本 5.2.15上面这张图许多人都看过,本文试图从源码的角度带大家分析一下该过程。1. ContextLoaderListener首先我们从 ContextLoaderListener 讲起,它继承自 ServletContextListener,用于监听 Web 应用程序的启动与停止。C
2021-05-21 16:45:37
695
3
原创 ArrayBlocking 源码分析
ArrayBlocking 源码分析基本介绍属性方法构造方法put() 方法offer() 方法take() 方法poll() 方法基本介绍ArrayBlocking 是一个阻塞队列,底层结构使用数组。ArrayBlocking 是线程安全的队列,通过 ReentrantLock 保证元素入队和出队时的数据的一致性。ArrayBlocking 通过 ReentrantLock 控制线程访问队列时的公平性。属性/** 使用数组模拟队列存储数据 */final Object[] items;
2021-03-23 22:02:24
134
原创 ReentrantLock 原理
ReentrantLock 原理非公平锁实现原理加锁流程解锁流程ReentrantLock 主要是通过 AQS + CAS 的方式实现加锁和解锁原理。这里先说一下重要的几个属性。state 标记是否加锁成功或是否发生锁重入exclusiveOwnerThread 当前拥有锁的线程waitStatus 线程等待状态CANCELLED 值为1,表示取消获取锁,会被从队列中删除SIGNAL 值为-1,表示等待队列中的下一个线程需被阻塞CONDITION 值为-2,表示当前线程等待被唤醒PRO
2021-03-23 13:24:11
449
原创 synchronized 关键字原理
synchronized 关键字原理synchronized 基本使用修饰代码块修饰非静态方法修饰静态方法synchronized 原理Monitor 概念synchronized 基本使用修饰代码块public void test() { synchronized(this) { }}给对象加锁。线程若想进入 synchronized 修饰的的代码块,需要获取对象的锁。修饰非静态方法public synchronized void test() {}// 等价于public
2021-03-04 15:06:02
127
原创 volatile 关键字的作用与原理
volatile 关键字的作用与原理线程的原子性、可见性、有序性原子性可见性有序性内存屏障加载屏障(读屏障)存储屏障(写屏障)获取屏障(读屏障)释放屏障(写屏障)volatile 关键字的作用与原理保障原子性保障可见性保障有序性线程的原子性、可见性、有序性原子性原子性是指在一个操作中就是 cpu 不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行。如果一个操作是原子性的,那么多线程并发的情况下,就不会出现变量被修改的情况。在 Java 中,除了 long 和 double 类型
2021-03-02 09:47:55
300
原创 CorsWebFilter 解决跨域请求问题
如在浏览器控制台看到类似于 xxx has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the request resouce.,则是出现了跨域请求问题。CorsWebFilter 可以用于解决跨域请求,配置也很简单。/** * 跨域请求配置 */@Configurationpublic class CorsConfig { @Bean public Cors
2021-01-27 19:56:22
5670
1
原创 mybatis-spring中的缓存失效问题
一. mybatis中的一级缓存首先我们来说一下mybatis中的一级缓存。mybatis中使用默认的SQLSession——DefaultSqlSession,每一个DefaultSqlSession中都持有一个Executor——BaseExecutor,BaseExecutor中含有一个属性localCache,localCache便是mybatis中的一级缓存。当用户初次发起查询时,会从数据库查询数据,并将查询结果保存在localCache中。private <E> List&l
2020-12-19 00:10:03
396
1
原创 SpringSecurity学习日记(5):防Csrf攻击
一.CSRF是什么?CSRF(Cross-site request forgery)跨站请求伪造,也被称为One Click Attack或者Session Riding,通常缩写为CSRF或XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS)CSRF通过伪装成受信任用户的请求来利用受信任的网站。CSRF是一种依赖web浏览器的、被混淆过的代理人攻击(deputy attack)。二.CSRF的原理下图解释了csrf攻击的思想(图片来自博客: 浅谈CSRF攻击方式)大致过程就是当你成功
2020-11-24 14:16:40
530
原创 ArrayList中以集合为参数的构造方法
我们先来看下ArrayList中以集合为参数的构造方法public ArrayList(Collection<? extends E> c) { // 将c中的数组克隆一份放入elementData 中 elementData = c.toArray(); // 判断数组长度是否为0 if ((size = elementData.length) != 0) { // c.toArray might (incorrec
2020-11-21 15:23:54
1560
原创 RandomAccess接口的主要作用
在List集合这个大家族中,有许多类型的List实现了RandomAccess接口,那么这个接口有什么作用呢。通过查看RandomAccess的源码我们可以知道,这个接口用来表明支持快速随机访问。快速随机访问的速度能做到比线性访问的速度还要快。源码中也举了个例子做对比。for (int i = 0, n = list.size(); i < n; i++) list.get(i); // runs faster than this loop:for (Iterator i
2020-11-19 23:19:44
557
原创 web项目中的常见乱码问题
许多人在写web工程获取前端传来的中文数据,常常是一段乱码。这里跟大家解释一下。假设你用的是jsp页面写前端。jsp的第一行就有声明<%@page pageEncoding="UTF-8"%>那么我们传递的中文数据会使用UTF-8 编码,而浏览器默认才用的是 ISO8859-1给你解码,那么先用 UTF-8 编码,再用ISO8859-1解码,你后端接收到的数据自然是一段乱码。碰到乱码问题先不要着急,你要想一下问题出在哪里,好多新手以为看到了UTF-8就觉得中文数据一定不会乱码了,那肯
2020-10-27 15:10:26
352
原创 SpringSecurity学习日记(4):记住我(remember-me)功能
在用户认证成功后,会调用AbstractAuthenticationProcessingFilter类的successfulAuthentication()方法protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, Servl
2020-10-22 13:27:04
550
原创 SpringSecurity学习日记(3):常用方法
自定义类继承WebSecurityConfigurerAdapter类可以实现自己的用户授权验证逻辑。我们需要在protected void configure(HttpSecurity http)方法中实现@Override protected void configure(HttpSecurity http) throws Exception { // 对请求进行验证 http.authorizeRequests() // 以下请求可以直接访问
2020-10-21 20:41:54
212
原创 SpringSecurity学习日记(2):用户登录
springboot版本为2.2.10pom.xml<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> .
2020-10-21 19:06:20
184
原创 SpringSecurity学习日记(1):springsecurity认证流程
SpringSecurity的核心是一条过滤器链1.UsernamePasswordAuthenticationFilter进行用户名和密码的认证。UsernamePasswordAuthenticationFilterpublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
2020-10-21 17:41:17
655
原创 @Transactional注解和synchronized同时使用时可能导致的数据安全问题
@Transactional注解用于开启事务,当在高并发情况下我们可能为了保证数据的安全使用悲观锁,可以在方法上使用synchronized使用悲观锁。但可能存在一些问题。@Transactional@Servicepublic class OrderService { @Autowired private OrderDao orderDao; public sychronized Order getOrder(int id) { return orderDao.getOrder(id);
2020-10-09 22:45:21
1083
1
原创 springboot中mybatis整合redis使用二级缓存
1.添加依赖<dependencies> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency>
2020-10-08 21:42:21
288
原创 docker搭建redis哨兵
基于上一篇的docker搭建redis主从服务器1.在conf目录下新建sentinel.conf,sentinel-26380.conf,sentinel-26381.conf三个文件2.编辑这三个文件vim sentinel.confport 26379 //指定端口号bind 0.0.0.0 //运行外部连接sentinel monitor mymaster 192.168.23.129 6379 2 //指定主服务器其他两个配置文件只需要改端口号就好了3.创建哨兵服务端doc.
2020-09-27 14:38:28
910
原创 docker搭建redis的主从服务器
1.在根目录下新建mydata文件夹用于放置我的一些文件的信息cd / #回到根目录mkdir mydata #新建mydata文件夹2.在mydata文件夹下新建redis文件夹存放有关redis的信息cd mydata #进入mydata文件夹mkdir redis #新建redis文件夹3.在redis目录下分别新建 conf, data 文件夹存放 主服务器的信息conf6380, data6380 文件夹存放 从服务器的信息cd redis #进入redis文件夹mkdir
2020-09-21 20:10:17
264
原创 springboot自动配置的原理
该篇适用于springboot 2.0及以上版本1.首先让我们看一下启动类@SpringBootApplicationpublic class SpringbootValidateApplication { public static void main(String[] args) { SpringApplication.run(SpringbootValidateApplication.class, args); }}启动类中使用了注解@SpringB.
2020-09-05 14:41:44
196
原创 关于<button>按钮的一个小坑
今天做一个项目时,用到了layui框架中的表单form,我想在点击按钮时发送一次ajax请求,获取json数据来显示想要的页面。每次点击后确实成功的发送了ajax请求,但都会刷新一次页面。这个问题困扰了我好久。后来终于知道原来是中的属性type的问题。关于标签的属性type,Internet Explorer 的默认类型是 “button”,而其他浏览器中(包括 W3C 规范)的默认值是**“submit”**。因为我运行页面用的是Chrome,默认是"submit"类型,当每点击一次按钮时,都会向服务器
2020-08-20 09:08:25
346
原创 shiro程序遇到java.lang.IllegalStateException: setAttribute: Session already invalidated错误
今天自己做一个项目时,想用thymeleaf模板动态显示登陆的用户名。所以在登陆的方法中用Session存储用户名,但遇到了java.lang.IllegalStateException: setAttribute: Session already invalidated 这个错误。先来分析一下。这是我原来的代码。@PostMapping("/login") public String login(String username, String password, HttpSession ses
2020-08-18 11:33:19
1981
原创 springboot实现国际化
在spring中提供了一个接口MessageSource来实现国际化。springboot中已经对国际化做了自动配置,自动配置MessageSourceAutoConfiguration,接下来我们看一下该类。@Bean@ConfigurationProperties(prefix = "spring.messages")public MessageSourceProperties messageSourceProperties() { return new MessageSourcePropert
2020-07-22 12:20:22
420
原创 springboot-定制错误页面
之前我有篇文章讲解了一下springboot的错误处理机制,这篇文章讲解一下在springboot中定制错误页面。先看以下项目结构我的错误页面都放在了templates的error文件夹下,这样可以使用模板引擎处理(我这里使用Thymeleaf模板引擎)1.默认处理方式当你未写任何处理错误的代码时,则会默认调用BasicErrorController类中的errorHtml()方法,跳转到相应的视图。(404错误跳转到404.html页面, 其他类型的跳到4xx.html页面,500错误跳转到50
2020-07-10 18:28:09
491
原创 springboot的错误处理机制(源码解析)
在 ErrorMvcAutoConfiguration类中注册了许多错误处理类。ErrorPageCustomizer 错误页面定制器BasicErrorController 错误页面处器DefaultErrorViewResolver 默认错误视图处理器ErrorPageCustomizer类中有一个方法registerErrorPages()获取了错误路径。获取的路径为/error。当出现错误时,errorPageCustomizer就会生效,并来到/error请求,由BasicErr
2020-07-10 16:47:41
334
原创 springboot中的异常处理
在springboot项目中,程序出现异常时,会默认跳转到resources/templates目录下的error.html页面。我们可以自己编写方法来处理异常。1.通过@ExceptionHandler注解异常将@ExceptionHandler注解加在方法上,通过value属性值指定要处理的异常@Controllerpublic class UserController { @RequestMapping("/getUser") public String getUser()
2020-07-10 00:40:36
698
原创 @ConfigurationProperties注解
使用@PropertySource注解读取配置文件的方法,是代码复用性大大降低。因此引入了@ConfigurationProperties注解,自定义配置类,通过配置类获取配置文件中的信息,提高程序的灵活性。在springboot中,@ConfigurationProperties会获取工程配置文件中的信息(即application.properties 和 application.yml)。通过属性prefix指定获取配置文件中的值。如:application.ymljdbc: url: jd
2020-07-09 01:25:56
617
原创 @Value注解
@Value注解主要用于读取配置文件中的信息使用方式(1) 字面量可以直接获取字面量的值如:@Value(10)@Value(“Tom”)(2) #{}可以进行基本的算数运算如:@Value(10-2)(3) ${}读取配置文件中的值如:配置文件jdbc.username=rootjdbc.password=rootjdbc.driverClassName=com.mysql.jdbc.Driver@Value("${jdbc.username}")private S
2020-07-09 01:11:38
1233
原创 JDK动态代理
实现动态代理的步骤:1.创建目标类2.定义一个功能接口,接口中包含了目标类的功能3.创建InvocationHandler接口的实现类,在invoke方法中完成代理类要实现的功能4.使用Proxy类的newProxyInstance方法创建代理类。我在这里以果农卖水果为例:第一步:创建果农类,果农有卖水果的方法,方法定义在接口中/**果农类*/public class FruitFamer implements SellFruit{ @Override public i
2020-06-17 17:38:05
153
原创 Java中通过super()调用父类构造器
我们可以在子类的构造器中,通过super关键字调用父类的构造器。//父类class Person { private String name; public Person() { }}//子类class Man extends Person{ private int age; public Man() { ...
2020-04-28 10:55:06
4913
1
原创 JAVA中在本类的一个构造器中调用其他构造器
我们在一个类中,可以在一个构造器中显式的调用本类的其他构造器。如:public class Person { private String name; //构造器一 public Person() { } //构造器二 public Person(String name) { this(); ...
2020-04-28 10:01:25
3051
原创 LeetCode 767. 重构字符串
给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同。若可行,输出任意可行的结果。若不可行,返回空字符串。示例 1:输入: S = “aab” 输出: “aba”示例 2:输入: S = “aaab” 输出: “”若最大的字符数大于字符串长度加1的一半,则不可行if (maxLen > (S.length + 1) / 2)return “”;...
2020-04-18 22:13:07
195
原创 ParameterizedType及其方法详解
我们在项目的BaseDao这个类中经常要用到ParameterizedType这个接口。写贴一段代码:public class BaseDao<T> { //Dbutils中的查询类 private QueryRunner queryRunner = new QueryRunner(); //用来接收子类的泛型的类型 private Class&l...
2020-04-16 16:34:18
10586
1
原创 谷歌验证码的使用
动态验证码的生成。不管在任意网站的注册或者登陆页面,经常需要我们填写验证码。今天就说一下谷歌验证码吧。首先,我们用一个img标签,引入它的路径。<img id="code_img" src="kaptcha.jpg">注意,这个src引入的可不是一张图片这么简单,它实际上是一个Servlet程序的路径。<servlet> <servlet-nam...
2020-04-08 19:52:26
4507
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人