Spring体系
2024-07-09 17:56:38 18 举报
AI智能生成
登录查看完整内容
Spring 2024年4月24日01:34:36:更新,完善内容,补充了JavaWeb相关 2024年6月22日02:00:58:SpringBoot配置文件相关完善、Spring 事务失效完善、Mybatis内容完善、Spring Cloud分布式事务完善 2024年7月9日17:56:11:整理了SpringBoot里的冗余内容
作者其他创作
大纲/内容
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
MybatisX代码生成
主键自动生成
属性填充
SQL打印
多数据源
分页插件
逻辑删除
用过的
Mybatis Plus
Nacos
服务注册与发现
配置中心
OpenFeign
LoadBalance
远程服务调用与负载均衡
反向代理
鉴权
流量控制
熔断
日志监控
能干嘛
Route
就是匹配条件
Predicate
请求鉴权
异常处理
。。。。
直接实现接口即可
全局默认过滤器GlobalFilters
单一内置过滤器GatewayFilters
自定义过滤器
类型
Filter
三大核心
Spring Cloud GateWay
服务网关
Sentinel
服务熔断降级
分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器「分别位于不同的分布式系统的不同节点之上」。一个大的操作由N多的小的操作共同完成。而这些小的操作又分布在不同的服务上。针对于这些操作,「要么全部成功执行,要么全部不执行」。
分布式事务的定义?
简而言之,必须在一致性与可用性之间做出选择
CAP(强一致性)
简而言之,我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性
BASE(最终一致性)
分布式理论
seata服务端
TC(事务协调者)
seata客户端,就是sdk
TM(事务管理者)
database
RM(资源管理者)
分布式事务涉及到哪些角色?
类似JDBC,是一套接口规范,各个数据库厂商基于这套接口规范进行了实现,通用了语言级的API。2PC和3PC衍生于XA协议
XA协议是什么?
分为准备阶段和提交阶段。准备阶段:TC向所有参与者发送准备请求,询问是否可以准备提交事务。每个参与者要么准备好并锁住资源,要么拒绝准备。如果所有参与者都准备好了,TC向所有参与者发送提交请求,否则发送回滚请求。
详情
无侵入,好用
优点
阻塞同步,性能差,不适合长事务
TC单点故障风险
缺点
2PC(二段提交)
3PC 是 2PC 的改进版本,增加了一个中间阶段来减少TC和参与者之间的等待时间。准备阶段:与 2PC 类似,TC询问所有参与者是否可以准备提交事务。预提交阶段:如果所有参与者都准备好了,TC者向所有参与者发送预提交请求,参与者预提交并继续等待最终指令。提交阶段:TC发送提交请求,所有参与者正式提交事务。
解决单点问题,以及通过超时机制减少阻塞
协议更复杂,实施成本较高,没有从根本上解决性能和数据一致性的问题
3PC(三段提交)
对于3PC的落地实现
Seta-AT(√)
刚性兑付(强一致性)
2PC改良版,包含尝试(Try)、确认(Confirm)和取消(Cancel)三个步骤。Try 阶段:资源预留或锁定,检查并锁定需要的资源。Confirm 阶段:正式提交,执行实际的事务操作。Cancel 阶段:取消操作,释放预留的资源或撤销尝试阶段的操作。
灵活性高,可以针对具体业务场景优化。TCC 完全不依赖底层数据库,能够实现跨数据库、跨应用资源管理,可以提供给业务方更细粒度的控制。
设计实现复杂,侵入性非常强,需要处理好资源预留和取消的逻辑。
TCC三段补偿
每一个服务的db下额外建立一张业务无关的表,基于对这张表记录的操作实现事务操作
无锁,快
藕和度大,不可复用
本地消息表
将两个事物之间通过消息中间件进行异步解耦,类似本地消息表,但是把表放到MQ里了。
1.主动者发送\"待发送\"消息给消息微服务2.消息微服务收到消息,进行持久化数据库操作并返回(返回就是调主动者提供的一个回查接口,告诉主动者我持久化好消息了)3.主动者收到消息微服务的返回后,执行本地的业务,持久化到数据库4.主动者执行完业务,向消息微服务发送通知5.消息微服务收到通知,将数据库里的待发送状态改为已发送6.以上操作执行都ok,接着消息微服务把消息发到MQ7.被动者监听MQ获取消息内容8.被动者拿到消息内容,进行业务处理9.被动者处理完业务,通知消息微服务把数据库里的消息记录改为已完成或者直接删除PS:细节处理1.保证消息投递100%,定时任务轮询待发送状态的消息,通过主动者提供的状态查询接口确认消息状态,如果业务执行成功,向MQ发送消息并发消息状态改为已发送,如果业务失败,删除消息2.保证消息消费100%,,定时任务轮询已发送状态的消息,已过期的消息重新推到MQ,,被动者在保证幂等的情况下重新执行业务,,被动者执行完业务通知消息服务对消息进行状态修改为已完成或者删除消息
流程
@Translation+先处理本地,然后在通过MQ通知
分布式定时任务定时轮询消息服务,逼着上游向下游进行消息投递
怎么用
解耦,降低业务系统之间的耦合度
消息服务更加灵活,伸缩性强,独立维护,独立部署
相比本地消息表,降低开发成本,消息服务共用
主动者必须实现消息状态回查接口
轮询待发送和已发送两个过期时间的状态进行重试操作
需要分布式定时器实现两个任务
主动者通知被动者需要发两次消息,过于复杂
独立消息微服务+消息队列+分布式定时任务轮询(√)
适合最终一致性要求较低的业务,比如短信通知
确定
最大努力通知
柔性事务(最终一致性)
分布式事务的解决方案?
3PC的实现
AT 模式:基于 Seata 自身实现的两阶段提交,主要针对数据库操作。
AT模式
2PC改良版,不好用
TCC模式
长事务解决方案,不好用,你画内b状态机去吧
Saga模式
XA 模式使用起来与 AT 模式基本一致,用法上的唯一区别在于数据源代理的替换:使用 DataSourceProxyXA 来替代 DataSourceProxy
XA 模式:基于标准的 XA 协议,适用于跨多种资源的分布式事务。
XA模式
模式
Seata
分布式事务
Jaeger(我用过的)
Micrometer+ZipKin
SkyWalking
SpringBoot+MDC实现本地微服务链路追踪,结合feign拦截器实现分布式链路追踪
其他?
服务链路追踪
Spring Cloud Kubernetes
云原生
Spring Cloud
虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。
SpringBoot对上述Spring的缺点进行的改善和优化,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率,一定程度上缩短了项目周期。
为什么?
位于spring-boot.jar内部的application.properties或application.yml
默认配置
config目录下的application.properties或application.yml文件(file:./config/)
当前目录下的application.properties或application.yml文件(file:./)
类路径根目录下的application.properties或application.yml文件(classpath:/config/)
类路径根目录下的application.properties或application.yml文件(classpath:/)
应用配置文件
操作系统环境变量
命令行参数
配置加载顺序(后加载的配置会覆盖先加载的配置)
application-dev.properties
application-prod.properties
为了支持多环境配置,Spring Boot引入了profile的概念,可以创建多个环境的配置文件,通过spring.profiles.active参数指定
多环境配置
①启动创建ConfigurableEnvironment
②添加默认配置
③ConfigFileApplicationListener查找配置文件,加载到的每个配置文件会被添加到Environment中作为PropertySource,后加载的配置会覆盖先加载的配置
④根据profile.active处理Profile
⑤环境变量和系统属性,ConfigFileApplicationListener会将操作系统环境变量和JVM系统属性添加到Environment中
⑥处理命令行参数,并将其添加到Environment中
配置文件加载原理
大致原理:基于约定大于配置,本身内置了非常多的y依赖项集合,它们基于@Conditionnal注解进行注册,当我们在maven中添加了各种starter依赖后,满足装配条件的Bean会在启动时进行自动装配,实现方式看下面
定义在main方法入口类处,标注这是一个SpringBoot应用,用于启动sping boot应用项目
标注这个类这是一个配置Bean
@Configuration
@SpringBootConfiguration
把主程序所在的包的所有组件导入进来
@Import(AutoConfigurationPackages.Registrar.class)
@AutoConfigurationPackage
加载所有自动配置类:加载starter导入的组件
在src/main/resources的META-INF/spring.factories
@Import(AutoConfigurationImportSelector.class)
@EnableAutoConfiguration
排除前面已经扫描进来的配置类、和自动配置类
@ComponentScan
tips:注解的执行顺序的倒叙的
@SpringBootApplication
①每一个Starter都有一个spring-boot-autoconfigure依赖
②spring-boot-autoconfigure依赖的包里有一个META-INF/spring.factories文件,里面指定了所有启动要加载的自动配置类
③@EnableAutoConfiguration 会自动的把上面文件里面写的所有自动配置类都导入进来。xxxAutoConfiguration 是有条件注解进行按需加载的,不是无脑加载
④xxxAutoConfiguration给容器中导入一堆组件,组件都是从 xxxProperties中提取属性值
⑤xxxProperties又是和配置文件进行了绑定
步骤
自动装配
常用注解
@Scope
@Bean
@Import
@Controller、 @Service、@Repository、@Component
加载xml配置,一般是放在启动main类上
@ImportResource
组件注册
@ConditionalOnClass
@ConditionalOnMissingClass
@ConditionalOnBean
@ConditionalOnMissingBean
@ConditionalOnXxx
条件注解
声明组件的属性和配置文件哪些前缀开始项进行绑定
@ConfigurationProperties
快速注册组件
场景:SpringBoot默认只扫描自己主程序所在的包。如果导入第三方包,即使组件上标注了 @Component、@ConfigurationProperties 注解,也没用。因为组件都扫描不进来,此时使用这个注解就可以快速进行属性绑定并把组件注册进容器(这个还需要被标注的第三方组件类上本身标注了@configurationProperties注解)
● @EnableConfigurationProperties● 1、开启Sheep组件的属性绑定● 2、默认会把这个组件自己放到容器中常用于导入第三方包
@EnableConfigurationProperties
application.properties定义属性,直接使用@Value注入即可
@Value
属性绑定
用来获得请求url中的动态参数
@PathVariable
支持将返回值放在response体内,而不是返回一个页面
@ResponseBody
获取request请求的参数值
@RequestParam
组合@Controller和@ResponseBody
@RestController
Web MVC
@Order(1),值越小优先级超高,越先运行
@Order
AOP
spring容器初始化时,要执行该方法
@PostConstruct
生命周期
常用注解(分类版本)
①创建SpringBoot项目,添加spring-boot-starter依赖
绑定配置的xxxProperties类,通过@ConfigurationProperties(prefix = \"xxx\")和配置文件进行绑定
②编写模块功能,引入模块所有需要的依赖
③编写xxxAutoConfiguration自动配置类,帮其他项目导入这个模块需要的所有组件
④编写配置文件META-INF/spring.factories指定启动需要加载的自动配置
⑤打包,发布到Maven仓库
⑥其他项目引用
个人理解:starter里边写的那些虽然加了各种注解,看上去是被Spring托管了,但是基于SpringBoot的扫描规则,这些类根本就不会被扫描到。因此,为了装载这些类,我们通过创建一个Configuration类,在类中import其他要托管的类,然后把配置类的全类名加到spring.factories文件里,通过另外一种加载途径实现装载
自定义starter
Spring Boot(核心思想:约定大于配置)
一套Java与数据库系统进行通信的接口规范,Java提供接口,由各个数据库厂商进行实现。
JDBC是什么?
Class.forName
Driver
Connection
Statement
避免SQL注入,预编译
PrepareStatemant
ORM思想,将查询结果映射到类
ResultSet
Druid
Hikari
数据库连接池
事务
DBUtil工具类封装
JDBC
某种意义上来说,你可以认为它是一种规范,Java提供了对应的接口供我们实现
只执行一次
init()
来一次请求执行一次
service()
destory()
声明周期
Servlet
本质就是一个Servlet
JSP(JavaServer Pages)
一种可重用的 Java 类,通常用于封装数据和业务逻辑
JavaBean
三大核心组件
对请求和响应进行预处理和后处理
用于监视 Web 应用程序中的事件,并在事件发生时执行相应的操作
Listener
Interceptor 是在 Spring 框架中使用的一种拦截器,它是基于 Spring 框架的 AOP(面向切面编程)机制实现的
Filter 是 Servlet 规范中的一部分,它是基于 Java Servlet API 实现的
Interceptor 主要用于拦截 Spring MVC 控制器的方法调用,对请求进行预处理和后处理
Filter 是通过在 web.xml 文件中配置来指定对特定 URL 或者某些 Servlet 请求进行拦截和处理的
Interceptor 仅作用于 Spring MVC 的控制器方法,不会拦截对静态资源的请求
Filter 在 Servlet 容器中工作,对所有的请求和响应进行拦截,包括静态资源
Filter和Interceptor的区别:
Cookie 存储在客户端
Cookie 的生命周期由客户端控制
Cookie 可以存储少量的数据
Cookie 存储在客户端,可能会被篡改
Cookie
Session 存储在服务器端
Session 的生命周期由服务器控制
Session 可以存储大量的数据
Session 更安全,因为数据存储在服务器端
Session
JavaWeb
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
解决方式:反射
手动对象关系映射
解决方式:连接池?
数据库连接管理?
解决方式:预编译
SQL 注入攻击
xml配置
配置繁琐
结果集获取
ORM框架解决了什么问题:
通过实例化和使用它来创建SqlSessionFactory,创建完成后就可以丢弃它。所以它的最佳作用域是作为局部方法变量来使用。
SqlSessionFactoryBuilder
应用运行期间一直存在。它的最佳实践应该是单例的。最佳作用域是应用级别的作用域。
SqlSessionFactory
每一个线程都应该有自己的SqlSession实例。它是线程不安全的,不能被共享。最佳作用域是会话级别的。
SqlSession
从 SqlSession 中获得。
映射器实例
核心组件
select
insert
delete
update
sql片段复用
sql
自定义缓存
cache
cache-ref
结果集映射
resultmap
XML文件常用的顶级元素
${}直接使用字符串替换,使用的场景也比较固定,动态表名、列名
#{}使用PreparedStatement 进行预编译,效果就是会使用 ? 替代,用户入参使用的比较多,安全行高,可用避免SQL注入。MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。
还有一个#{}和${}的区别
基于内存的分页,查出所有记录再按偏移量和limit取结果
内置分页的缺点
ResultMap一般不用显示配置,默认会找同名的属性的类型进行转换,当然如果结果映射确实比较复杂,还是得显示配置。
ResultMap(强大的)
ResultType
结果映射
sqlSession级别
默认开启
Select语句会被缓存;Insert、Update、Delete语句会被刷新缓存;
一级缓存
Application级别
默认不开启
二级缓存
缓存
MyBatis对会话(Session)级别的一级缓存设计的比较简单,就简单地使用了HashMap来维护,并没有对HashMap的容量和大小进行限制
一级缓存是一个粗粒度的缓存,没有更新缓存和缓存过期的概念
默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存
MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能
要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行<cache/>
主要说一下缓存
语法<if test = \" 条件 \">条件通过需要执行的sql部分</if>
if
choose(when、otherwise)类似Java的switch
前面两中在特殊的情况下,会导致SQL格式出现问题,执行失败,这个就是比较智能,会根据不同情况进行处理
trim(where、set)
对集合进行遍历
foreach
动态SQL
常用插件(只需实现 Interceptor 接口,并指定想要拦截的方法签名即)
MyBatis
EJB不好用,开发难度高、性能差,而Spring的出现就是为了简化Java EE的开发,Spring是一个轻量级的Java EE开发框架
Spring的起源
非侵入式
DI是具体实现
IOC思想
组件化
容器化
Spring的优势
提供了一个 JDBC 的样例模板
提供与流行的“对象-关系”映射框架无缝集成的 API
ORM
提供一套 “消息生产者、消息消费者”模板用于更加简单的使用 JMS
JMS
支持编程和声明式事务管理。
Transaction
提供了一个支持 Object /XML 映射的抽象层实现
OXM
DataAccess/Integration
提供了简单的接口,用户只要实现响应的接口就可以快速的搭建 WebSocket Server,从而实现双向通讯。
WebSocket
提供了一个 Spring MVC Web 框架实现
提供了基本的 Web 开发集成特性
Web
Spring WebFlux 是 Spring Framework 5.x中引入的新的响应式web框架
WebFlux
提供了框架的基础部分,包括控制反转和依赖注入
Beans
封装了 Spring 框架的底层部分,包括资源访问、类型转换及一些常用工具类
core
建立在 Core 和 Beans 模块的基础之上,集成 Beans 模块功能并添加资源绑定、数据验证、国际化、Java EE 支持、容器生命周期、事件传播等。ApplicationContext 接口是上下文模块的焦点
context
提供了强大的表达式语言支持
spEl
Core
Spring 支持 Junit 和 TestNG 测试框架
Test
提供了面向切面编程实现
提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架
Aspects
Messaging
Spring核心组件(看一看就好)
控制反转是一种思想,用户管理Bean的行为转变为框架管理Bean,解放双手不用自己手动New对象,向容器“申请”。创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,达到一个解耦的效果
Bean 是由 Spring IoC 容器实例化、组装和管理的对象。
什么是Bean?
如何理解IOC?
XML
声明@ComponentScan,使用注解@Component,@Controller,@Service,@Repository声明要注册的Bean
代码方式:在配置类上添加@Configuration注解,在方法上添加@Bean注解,方法返回对象,本质上也可以认为是一个XML
IOC配置的三种方式
构造方法实例化
静态工厂方法实例化
实例工厂实例化
Bean的实例化方式
能避免循环依赖,项目在启动时如果存在循坏依赖,会抛异常提醒
保证对象的不变性,避免空指针异常
构造方法注入(推荐)
setter方法注入
Spring提供的,基于类型,结合@Qualifier注解可以byname
@Autowire
JSR250规范实现,基于name
@Resource
@Inject
注解注入(不知道对不对,官方文档里其实是只有构造和setter的,ChatGPT的回答是有这项的,但是它的回答是说这是基于字段的方式,通过在字段上添加注解实现)
依赖注入方式
no
byName
byType
constructor
自动装配(依赖注入的实现方式)
IOC容器初始化时创建
singleton单例,默认
获取Bean时创建
prototype多实例
request,web环境下
session,web环境下
application,Servlet上下文下
websocket(不了解)
Bean的作用域
1、Bean对象的创建(调用无参构造函数)
依赖注入
2、为Bean对象设置相关属性
需要实现后置处理器接口,这块逻辑对所有Bean生效
3、Bean后置处理器(初始化前)
不同的Bean可以定制化处理,使用@PostConstruct
4、Bean对象初始化(调用指定的初始化方法)
Subtopic
5、Bean后置处理器(初始化后)
6、Bean对象创建完成,使用
不同的Bean可以定制化处理,使用@PreDestroy
7、Bean对象销毁(执行指定销毁方法)
8、IOC容器关闭
Bean的生命周期
也可以直接用注解@PostConstruct
重写afterPropertiesSet()方法
实现InitializingBean接口
也可以直接用注解@PreDestroy
重写destroy()方法
实现DisposableBean
自定义Bean的生命周期
IOC(控制反转)
BeanFactory: 工厂模式定义了IOC容器的基本功能规范
BeanRegistry: 向IOC容器手工注册 BeanDefinition 对象的方法
两个顶层接口
初始化的入口在容器实现中的 refresh()调用来完成
容器解析得到 BeanDefinition 以后,需要把它在 IOC 容器中注册,这由 IOC 实现 BeanDefinitionRegistry 接口来实现。注册过程就是在 IOC 容器内部维护的一个HashMap 来保存得到的 BeanDefinition 的过程。这个 HashMap 是 IoC 容器持有 bean 信息的场所,以后对 bean 的操作都是围绕这个HashMap 来实现的.
初始化流程
第一层缓存(singletonObjects):单例对象缓存池,已经实例化并且属性赋值,这里的对象是成熟对象
第二层缓存(earlySingletonObjects):单例对象缓存池,已经实例化但尚未属性赋值,这里的对象是半成品对象;
第三层缓存(singletonFactories): 单例工厂的缓存
Spring只是解决了单例模式下属性依赖的循环问题;Spring为了解决单例的循环依赖问题,使用了三级缓存
Spring提早将对象暴露出来使用,解决循环依赖
@Lazy注解,延迟加载
修改文件名称,改变循环依赖类的加载顺序
@DependsOn注解,指定加载先后关系
生成代理对象产生的循环依赖
通过把bean改成单例的解决
多例循环依赖
使用@Lazy注解解决
构造器循环依赖
单例以外的循环依赖怎么解决?
循环依赖
Spring 只帮我们管理单例模式 Bean 的完整生命周期,对于 prototype 的 bean ,Spring 在创建好交给使用者之后则不会再管理后续的生命周期。
bean对象创建(调用无参构造器)
给bean对象设置属性
bean的后置处理器(初始化之前)
bean对象初始化(需在配置bean时指定初始化方法)
bean的后置处理器(初始化之后)
bean对象就绪可以使用
bean对象销毁(需在配置bean时指定销毁方法)
IOC容器关闭
Bean实例化
IOC源码分析
在哪里干
连接点 Join point
在哪里干的集合
切入点 pointcut
Before advice
前置通知
After returning advice
后置通知
Around advice
环绕通知是最常用的通知类型,从方法参数这中拿到JoinPoint自定义通知逻辑
环绕通知
After throwing advice
异常通知
After (finally) advice
最终通知
干什么
通知 Advice
在哪干和干什么集合
切面 Aspect
引入
对谁干
目标对象
怎么实现的
织入
怎么实现的一种典型方式
AOP代理
概念
AOP在运行时仍旧是纯的Spring AOP,并不依赖于AspectJ的编译器或者织入器
因为JDK动态代理是基于接口实现的,如果被代理的类没有实现任何接口,就无法生成对应的代理类,也就无法实现动态代理
有接口使用
JDK动态代理
非接口使用
CGLIB动态代理
通过动态代理技术(JDK动态代理或者CGLIB动态代理)在运行时动态将要增强的代码织入到目标类
动态织入
Spring AOP
编译期织入,在这个期间使用AspectJ的acj编译器(类似javac)把aspect类编译成class字节码后,在java目标类编译时织入,即先编译aspect类再编译目标类
静态织入
AspectJ
实现
用来定义一个切面。
@Aspect
用于定义切入点表达式。在使用时还需要定义一个包含名字和任意参数的方法签名来表示切入点名称,这个方法签名就是一个返回值为void,且方法体为空的普通方法。
@pointcut
用于定义前置通知,相当于BeforeAdvice。在使用时,通常需要指定一个value属性值,该属性值用于指定一个切入点表达式(可以是已有的切入点,也可以直接定义切入点表达式)。
@Before
用于定义后置通知,相当于AfterReturningAdvice。在使用时可以指定pointcut / value和returning属性,其中pointcut / value这两个属性的作用一样,都用于指定切入点表达式。
@AfterReturning
用于定义环绕通知,相当于MethodInterceptor。在使用时需要指定一个value属性,该属性用于指定该通知被植入的切入点。
@Around
用于定义异常通知来处理程序中未处理的异常,相当于ThrowAdvice。在使用时可指定pointcut / value和throwing属性。其中pointcut/value用于指定切入点表达式,而throwing属性值用于指定-一个形参名来表示Advice方法中可定义与此同名的形参,该形参可用于访问目标方法抛出的异常。
@After-Throwing
用于定义最终final 通知,不管是否异常,该通知都会执行。使用时需要指定一个value属性,该属性用于指定该通知被植入的切入点。
@After
注解
配置方式
实现org.springframework.core.Ordered 接口,较低的那个有更高的优先级
较低的那个有更高的优先级
用Order注解
增强通知的顺序
总结来说就是 Spring AOP更易用,AspectJ更强大
Spring AOP 还是 AspectJ?
AOP(面向切面编程)
Spring默认在目标类实现接口时是通过JDK代理实现的,只有非接口的是通过Cglib代理实现的。当设置proxy-target-class为true时在目标类不是接口或者代理类时优先使用cglib代理实现
AOP源码分析
可以进行自定义粒度的事务管理
编程式事务
这个用的比较多,好用,方便
声明式事务
管理事务的方式
只读
默认无
超时
rollbackFor属性:需要设置一个Class类型的对象
rollbackForClassName属性:需要设置一个字符串类型的全类名
noRollbackFor属性:需要设置一个Class类型的对象
rollbackFor属性:需要设置一个字符串类型的全类名
回滚策略
DEFAULT
READ_UNCOMMITTED
READ_COMMITTED
REPEATABLE_READ
SERIALIZABLE
事务的隔离级别
当事务方法被另一个事务方法调用时,必须指定事务应该如何传播
没有就新建,有就加入
TransactionDefinition.PROPAGATION_REQUIRED(√)
不管有没有,直接开启一个新事务,开启的新事务和之前的事务不存在嵌套关系,之前事务被挂起
TransactionDefinition.PROPAGATION_REQUIRES_NEW(√)
有事务的话,就在这个事务里再嵌套一个完全独立的事务,嵌套的事务可以独立的提交和回滚。没有事务就和REQUIRED一样
TransactionDefinition.PROPAGATION_NESTED
有就加入,没有就抛异
TransactionDefinition.PROPAGATION_MANDATORY
有就加入,没有就不管了
TransactionDefinition.PROPAGATION_SUPPORTS
不支持事务,存在就挂起
TransactionDefinition.PROPAGATION_NOT_SUPPORTED
不支持事务,存在就抛异常
TransactionDefinition.PROPAGATION_NEVER
事务的传播行为
事务@Transactional属性
异常
事务配置没配好
多线程调用,多线程父子线程回滚异常,这玩意没法解决,别用
没有commit或者rollback
粗心
方法权限不是pubilc
方法被final修饰导致aop失效
同一个类中的方法调用没触发aop
AOP失效
异常不匹配(默认是RuntimeException.class)
事务的配置没配好
Bean没被Spring托管
抛出的异常被try catch吞掉处理了,解决:catch后再抛一个,或者catch里直接手动回滚
事务失效的场景
事务管理(基于Spring AOP实现)
Spring Framework
Spring MVC是Spring在Spring Container Core和AOP等技术基础上,遵循上述Web MVC的规范推出的web开发框架,目的是为了简化Java栈的web开发
执行流程
更简洁的Web 层的开发
强大的约定大于配置的契约式编程支持
灵活的URL 到页面控制器的映射
非常容易与其他视图技术集成,如 Velocity、FreeMarker 等等
非常灵活的数据验证、格式化和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的API
灵活的本地化、主题等解析
简单的异常处理
静态资源的支持
支持Restful 风格
为我们提供了什么特性?
主要读取web.xml中servlet参数配置,并将交给子类方法initServletBean()继续初始化
initWebApplicationContext用来初始化和刷新WebApplicationContext
initWebApplicationContext()
调用initStrategies(context)方法对DispatcherServlet中的组件进行初始化
onRefresh()
initHandlerXXX
SpringMVC实现原理之DispatcherServlet的初始化过程
Spring MVC
Spring
0 条评论
回复 删除
下一页