Spring Security 授权 在 loadUserByUsername 方法,在查询数据库用户信息的时候,同时查询出用户的权限,这里以角色名代指权限。在 loadUserByUsername 方法,在查询数据库用户信息的时候,同时查询出用户的权限,这里以角色名代指权限。在 loadUserByUsername 方法,在查询数据库用户信息的时候,同时查询出用户的权限,这里以角色名代指权限。通过 RBAC 获取到用户的具体权限后,再通过 Security 的 用户-权限-资源 来进行权限控制。HttpSecurity 权限配置。
springsecurity 身份认证 自定义认证接口的作用是做用户认证成功后执行的操作处理器接口的作用是做用户认证失败后执行的操作处理器接口的作用是做用户登场后执行的操作请求未认证处理逻辑可以控制一个账号的最大登录数量自定义和@Slf4j/*** 认证成功*/@Overridelog.info("返回成功-------------->");res.put("message", "登录成功");// 用户身份信息// 用户凭证信息// 用户的权限信息/*** 认证失败*/@Override。
Spring Boot日志 trace:微量,少许的意思,级别最低,一般记录了框架底层的日志,很少使用。fatal:致命的,因为代码异常导致程序退出执行的事件,例如jvm系统崩溃。warn:警告,不影响使用,但需要注意的问题,例如类的版本过时了。error:错误信息,级别较高的错误日志信息;debug:需要开发调试时候的关键信息打印;info:普通的打印信息(默认日志级别);SpringBoot预定义两个组。日志门面(日志的抽象层)all :打印所有的日志。off :关闭所有的日志。日志文件归档与滚动切割。
springBoot 核心原理 自定义stater步骤创建自定义starter项目,引入基础依赖编写模块功能,引入模块所有需要的依赖。编写自动配置类,帮其他项目导入这个模块需要的所有组件编写配置文件指定启动需要加载的自动配置其他项目引入即可使用自定义配置可以在配置文件中有提示。
spring boot 基础特性 Springboot四大组件spring boot的依赖管理profiles 提供了环境隔离能力,可以快速切换开发、测试、生产环境Profile 配置文件{profile}yaml文件。
AQS 抽象队列同步器 非公平锁的tryAcquire 方法会先判断锁的状态state是否为0,为0说明没有被其他线程占用,就立即使用cas操作变更state为1,变更成功就把持有锁的线程设置为自己,变更失败就表示加锁失败。AQS的tryRelease方法,同样没有做实现,需要子类自己去实现,下面是ReentrantLock的实现。AQS类的tryAcquire方法只是做了规范,方法内直接抛出异常,所以这个方法需要由子类去实现。如果锁的状态为1,说明锁已经被占用,在比较当前线程和持有锁的线程是否一致,不一致就加锁失败。
JMM内存模型 变量的写操作和读操作之间是可以被中断的,也就是在读取或者修改 volatile 变量的过程中,其他线程可能会对这个变量进行修改,但是 volatile 修饰的变量,只是保证了从主内存加载到工作内存的值是最新的,并不能保证对变量的操作是原子性的。如果不加volatile,因为初始化一个对象分为:分配内存空间,初始化对象,将对象指向分配的内存空间这三步,不加volatile ,对变量的修改,其他线程不可见,下面代码不加volatile 会卡死,加上才能正常执行。读屏障:在读取 volatile 变量时。
synchronized锁 所以只需要锁在第一次被拥有的时候,记录下线程的id,这样偏向线程会一直持有锁,这个线程后续进入和退出听不代码块的时候,不需要再次加锁和释放锁,而是去检查 mark word 中的偏向线程id是不是自己。偏向锁会偏向于第一个访问到锁的线程,且只有偏向锁被其他线程竞争,持有偏向锁的线程才会释放锁,否则线程是不会主动释放锁的,而对于持有偏向锁的线程也就不需要触发同步,就能在没有资源竞争的情况下消除了同步语句。当线程自旋达到一定次数,仍然没有获得锁,也就是有大量线程在竞争锁,那么就会升级锁为重量级锁。
JUC原子操作类 对象的属性修改原子类,可以用线程安全的方式操作非线程安全对象内的某些字段,例如:某个对象有多个属性,但是只有少量字段需要频繁更新,加锁虽然可以保证线程安全,但是有可能会锁住整个对象,所以可以用原子更新代替加锁。getProbe()方法,获取线程的hash值,如果返回0,会重新计算一个hash值,重新计算后,认为线程本次操作没有竞争关系,把竞争标志改为 true ,也就是不存在冲突。如果数组的长度 n大于当前cpu的核数,就不可扩容,然后重置当前线程的hash值,让线程重新循环参与竞争。
JUC AQS ReentrantLock源码分析 非公平锁的tryAcquire 方法会先判断锁的状态state是否为0,为0说明没有被其他线程占用,就立即使用cas操作变更state为1,变更成功就把持有锁的线程设置为自己,变更失败就表示加锁失败。AQS类的tryAcquire方法只是做了规范,方法内直接抛出异常,所以这个方法需要由子类去实现。调用lock方法加锁,除非是非公平锁能直接拿到锁,其他情况下都是在调用acquire 方法。如果锁的状态为1,说明锁已经被占用,在比较当前线程和持有锁的线程是否一致,不一致就加锁失败。取消正在进行的获取尝试。
volatile 无法保证原子性 案例展示 变量的写操作和读操作之间是可以被中断的,也就是在读取或者修改 volatile 变量的过程中,其他线程可能会对这个变量进行修改,但是 volatile 修饰的变量,只是保证了从主内存加载到工作内存的值是最新的,并不能保证对变量的操作是原子性的。所以在多线程环境下,对线程的操作结果可能会丢失,想要在多线程情况下修改主内存的共享变量必须加锁来保持同步。在 Java 中,原子性是指一个操作是不可中断的,要么都执行要么都不执行。例如:下面的代码不管加不加 volatile ,执行结果都会出错。
redis分布式锁 - 加锁的目的是为了防止代码的重复执行,在单机情况下,可以使用 jvm的锁:lock和synchronized进行加锁- 但是在分布式系统下,每个jvm是相互隔离的,JVM锁没有互斥性,所以需要引入第三方进行加锁