Springboot问题汇总
1. 编写starter时,引用后无法获取到bean
环境:使用版本Springboot3.1.4版本
问题:之前写starter的时候,一直是按照网上的教程,大部分是Springboot2.x版本,但自己使用了最新版本Springboot3.1.4版本,所以一直不成功。
深入代码查看后,发现以下跟老版本不一致。
新版本:
SpringBootApplication --> EnableAutoConfiguration --> AutoConfigurationImportSelector.getCandidateConfigurations --> ImportCandidates.load --> LOCATION --> "META-INF/spring/%s.imports"
老版本:
SpringBootApplication --> EnableAutoConfiguration --> AutoConfigurationImportSelector.getCandidateConfigurations --> SpringFactoriesLoader.loadFactoryNames --> Factories_RESOURCE_LOCATION --> "META-INF/spring.factories"
所以按照新版 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 进行编写的,可以正常识别。
注意:
这里的内容也不一样了,之前是需要写入一行,新版本支持多行格式
Enumeration<URL> urls = findUrlsInClasspath(classLoaderToUse, location);
List<String> importCandidates = new ArrayList<>();
while (urls.hasMoreElements()) { // 如果有多行,直接支持了,把所有的都加入到importCandidates中去了
URL url = urls.nextElement();
importCandidates.addAll(readCandidateConfigurations(url));
}
SpringSecurity
SpringSecurity从入门到精通
课程介绍
本课件由三更草堂录制, 如果侵权,请联系micah.shi@gmail.com

0. 简介
Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro,它提供了更丰富的功能,社区资源也比Shiro丰富。
一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较多,因为相比与SpringSecurity,Shiro的上手更加的简单。
一般Web应用的需要进行认证和授权。
认证:验证当前访问系统的是不是本系统的用户,并且要确认具体是哪个用户
授权:经过认证后判断当前用户是否有权限进行某个操作
而认证和授权也是SpringSecurity作为安全框架的核心功能。
1. 快速入门
1.1 准备工作
我们先要搭建一个简单的SpringBoot工程
① 设置父工程 添加依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
② 创建启动类
@SpringBootApplication
public class SecurityApplication {
public static void main(String[] args) {
SpringApplication.run(SecurityApplication.class,args);
}
}
③ 创建Controller
JavaAtomic工具类
Atomic*工具类
AtomicBoolean
1. 成员变量
// 对应的类中的成员变量句柄
private static final VarHandle VALUE;
// 存储变量的值
private volatile int value;
2. 核心
set时使用句柄(VarHandle)来进行设置value,获取时使用value进行获取
AtomicInteger
1. 成员变量
private static final Unsafe U = Unsafe.getUnsafe();
private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value");
private volatile int value;
2.核心
与Boolean类似
AtomicLong
1. 成员变量
Atomic*Array工具类
AtomicIntegerArray
1. 成员变量
private static final VarHandle AA = MethodHandles.arrayElementVarHandle(int[].class);
private final int[] array;
Java线程
线程
概念
- Java线程是什么
Java的线程,是运行在JVM的程序上的基本执行单元, Java针对线程抽象出Thread对象的概念。
- Java线程分类
Thread分为守护线程和非守护线程,当JVM启动时,伴随一个非守护线程的运行,我们称之为主线程/main函数,当JVM所有的非守护线程都销毁时,JVM实例也会销毁;
- Java线程生命周期
Java线程包含6个状态:NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED
- 多线程优缺点
JVM支持多线程,正确使用多线程能大大提高程序的服务能力,同时也引入程序的复杂度和线程安全问题(不正确使用)。
状态Thread.State
一个线程在指定的时刻上,只能存在一个状态;JVM的线程状态和操作系统的线程状态不是一一对应的。了解线程状态可用于分析线程问题/监控,不建议通过判断线程状态来进行逻辑处理

NEW(新建)
一个尚未启动的线程处于这一状态。(A thread that has not yet started is in this state.)
尚未启动的线程处于这一状态,即尚未调用start()
Theard t = new Theard();
RUNNABLE(可运行)
一个正在 Java 虚拟机中执行的线程处于这一状态。(A thread executing in the Java virtual machine is in this state.)
JVM中可执行的线程处于这一状态
Theard t = new Theard();
t.start();
BLOCKED(阻塞)
一个正在阻塞等待一个监视器锁的线程处于这一状态。(A thread that is blocked waiting for a monitor lock is in this state.)
Java内存模型
Java内存模型(JMM)
概念
Java内存模型(Java Memory Model,JMM),用于屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。
Java内存模型(不仅仅是JVM内存分区):调用栈和本地变量存放在线程栈上,对象存放在堆上。
堆栈存放规则

- 一个本地变量可能是原始类型,在这种情况下,它总是“呆在”线程栈上。
- 一个本地变量也可能是指向一个对象的一个引用。在这种情况下,引用(这个本地变量)存放在线程栈上,但是对象本身存放在堆上。
- 一个对象可能包含方法,这些方法可能包含本地变量。这些本地变量仍然存放在线程栈上,即使这些方法所属的对象存放在堆上。
- 一个对象的成员变量可能随着这个对象自身存放在堆上。不管这个成员变量是原始类型还是引用类型。
- 静态成员变量跟随着类定义一起也存放在堆上。
- 存放在堆上的对象可以被所有持有对这个对象引用的线程访问。当一个线程可以访问一个对象时,它也可以访问这个对象的成员变量。如果两个线程同时调用同一个对象上的同一个方法,它们将会都访问这个对象的成员变量,但是每一个线程都拥有这个成员变量的私有拷贝。