Spring 注解编程AOP
-
AOP
的常用注解 -
AOP
的源码分析 - 事务的注解与源码分析
AOP
的常用注解
Aspect-Oriented Programming 面向切面编程,主要包含切面
Aspect
,切入点Pointcut
以及通知(切入时机)Advice
,通知包含方法执行之前Before
、方法执行之后After
、方法环绕Around
,通知方法参数有JoinPoint
,Around
方法参数有ProceedingJoinPoint
JoinPoint
只能放在方法的第一个参数,主要方法如下
getArgs()
返回方法的参数getThis()
返回代理对象getTarget()
返回目标对象getSignature()
返回通知方法的签名toString()
返回通知方法有用描述ProceedingJoinPoint
只能放在方法的第一个参数,主要方法如下
proceed(Object[] args)
执行目标方法
@EnableAspectJAutoProxy
启用切面,相当于xml
中aop:aspectj-autoproxy
1 |
|
proxyTargetClass
对应xml
中属性proxy-target-class
,是否启用CGLIB
exposeProxy
对应xml
中属性expose-proxy
,是否暴露代理,设置为true的时候,可以通过AopContext.currentProxy()
获取代理实例(通过ThreadLocal
进行实现的)
@Aspect
切面,横切多个类的关系的模块化
1 |
|
相当于xml
中
1 |
|
@Pointcut
切点,执行方法的切点
1 |
|
相当于xml
中
1 |
|
切入点表达式
execution
切入表达式,这个Spring中最常用的execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
execution(public * *(..))
所有包下的public方法execution(* set*(..))
所有已set
开头的方法`*execution(* com.xyz.service.AccountService.*(..))AccountService
下的所有方法execution(* com.xyz.service.*.*(..))
service
包下的所有类的方法execution(* com.xyz.service..*.*(..))
service
包以及子包的所有类的方法
within
within(com.xyz.service.*)
service包下的所有类的方法within(com.xyz.service.*)
service包以及子包所有类的方法
this
指定代理实现的接口this(com.xyz.service.AccountService)
指定AccountService
接口下的所有方法target
执行目标对象实现的接口target(com.xyz.service.AccountService)
指定AccountService
接口下的所有方法args
执行目标方法的参数args(java.io.Serializable)
有Serializable
参数的所有方法@target
@target(org.springframework.transaction.annotation.Transactional)
目标对象有@Transactional
注解的类所有方法@within
@within(org.springframework.transaction.annotation.Transactional)
目标对象有@Transactional
注解申明的类所有方法@annotation
@annotation(org.springframework.transaction.annotation.Transactional)
有@Transactional
注解的所有方法@args
@args(com.xyz.security.Classified)
有@Classified
注解的单参数方法bean
- b
ean(*ServiceImpl)
所有以ServiceImpl
结尾Bean的所有方法
- b
@Before
在切点的方法之前执行方法
1 |
|
相当于xml
中
1 |
|
@AfterReturning
在切点的方法执行返回执行
1 |
|
相当于xml
中
1 |
|
@AfterThrowing
在切点的方法执行抛出异常执行
1 |
|
相对于xml
中
1 |
|
@After
在切点方法执行之后执行,也就是在@AfterReturning
或者@AfterThrowing
之前执行
1 |
|
相当于xml
中
1 |
|
@Around
在切点方法执行前后执行
1 |
|
相当于xml
中
1 |
|
AOP
的执行顺序
正常执行流程:@Around
-> @Before
-> @After
-> @AfterReturning
异常执行流程:@Around
-> @Before
-> @After
-> @AfterThrowing
切面的主要接口
PointCut
切入点
ClassFilter
类的过滤器MethodMatcher
方法的匹配器
Advice
通知
BeforeAdvice
前置通知AfterAdvice
后置通知AfterReturningAdvice
执行返回通知ThrowsAdvice
异常通知
MethodInterceptor
方法的拦截器(继承Advice)
MethodBeforeAdviceInterceptor
方法前置拦截器AspectJAroundAdvice
ApectJ
环绕拦截器AspectJAfterAdvice
ApectJ
后置拦截器AfterReturningAdviceInterceptor
后置返回拦截器AspectJAfterThrowingAdvice
后置异常拦截器
Advisor
通知器
Advice
通知
PointcutAdvisor
切入点通知器(继承Advisor)
Pointcut
切入点
动态代理的主要接口
AopProxy
Aop
动态代理
JdkDynamicAopProxy
Jdk
动态代理CglibAopProxy
Cglib
动态代理ObjenesisCglibAopProxy
扩展的Cglib
动态代理
这个是通过
org.springframework.aop.framework.DefaultAopProxyFactory
进行动态匹配生成,构建执行链org.springframework.aop.framework.DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
关联了Advisor
AOP
的源码分析
@EnableAspectJAutoProxy
注解通过@Import(AspectJAutoProxyRegistrar.class)
注册
- 实现
ImportBeanDefinitionRegistrar
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)
- 注册
org.springframework.aop.config.internalAutoProxyCreator
——AnnotationAwareAspectJAutoProxyCreator
,最高优先级
- 注册
AnnotationAwareAspectJAutoProxyCreator
实现主要接口
BeanFactoryAware
BeanFactory
回调接口InstantiationAwareBeanPostProcessor
实例化执行的接口BeanPostProcessor
Bean后置处理器
BeanFactoryAware
BeanFactory
回调接口
AbstractAdvisorAutoProxyCreator#setBeanFactory
AnnotationAwareAspectJAutoProxyCreator#initBeanFactory
ReflectiveAspectJAdvisorFactory
处理
Advice
通知注解@Around
、@Before
、@After
、@AfterReturning
、@AfterThrowing
构建了一个
PointcutAdvisor
(InstantiationModelAwarePointcutAdvisorImpl
)AspectJExpressionPointcut
PointCut
切点表达式Advice
通知
BeanFactoryAspectJAdvisorsBuilderAdapter
InstantiationAwareBeanPostProcessor
实例化执行的接口
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
实例化执行的方法
AbstractAutoProxyCreator#postProcessBeforeInstantiation
- 判断是否是通知Bean
Advice
、Pointcut
、Advisor
、AopInfrastructureBean
这几个类的子类@Aspect
注解的类- bean的名词是否以bean的Class名称开头并且以
.ORIGINAL
结束
- 是否需要跳过
- 获取
Advisor
通知器列表(获取到了InstantiationModelAwarePointcutAdvisorImpl
)
- 获取
- 是否自定义
TargetSourceCreator
,若是有直接执行createProxy
BeanPostProcessor
Bean后置处理器
BeanPostProcessor#postProcessAfterInitialization
初始化执行的方法
AbstractAutoProxyCreator#postProcessAfterInitialization
wrapIfNecessary
- 判断是否是通知Bean
- 是否需要跳过
- 判断是否有
Advice
通知的Bean创建代理createProxy
DefaultAopProxyFactory#createAopProxy
config.isProxyTargetClass()
- 接口或者是Proxy的子类,使用
JdkDynamicAopProxy
- 其他使用
ObjenesisCglibAopProxy
- 接口或者是Proxy的子类,使用
- 创建
JdkDynamicAopProxy
通过代码实现切面
实现一个PointAdvisor
1 |
|
实现一个MethodInterceptor
1 |
|
配置Bean信息
1 |
|
若是不希望拦截所有的方法,自行实现Pointcut
1 |
|
事务的注解与源码分析
事务的解决问题
脏读
一个线程在处理数据,事务还未提交;另一个线程可以读到此数据
重复读
一个线程读数据,另一个线程改数据,导致同一个线程获取的数据不一致。
幻读
一个线程读数据,另一个线程添加数据,导入同一个线程获取的数据条目不一致,多出来的条目称为幻行。
事务的隔离级别
Connection
READ_UNCOMMITTED
读未提交的READ_COMMITTED
读已提交REPEATABLE_READ
重复读SERIALIZABLE
串行事务的传播机制
TransactionDefinition
REQUIRED
必须以事务执行,若有事务,以当前事务执行,没有事务重新启动新事务执行SUPPORTS
支持事务执行,若有事务,用当前事务执行,没有事务不进行事务操作MANDATORY
支持事务执行,若有事务,用当前事务执行,没有事务抛错REQUIRES_NEW
以新事务执行NOT_SUPPORTED
支持无事务执行NEVER
无事务执行,有事务抛错NESTED
若是有事务存在,嵌套事务执行
常用注解
@EnableTransactionManagement
开启事务的注解
@Transactional
启用事务的注解
源码分析
@EnableTransactionManagement
通过@Import(TransactionManagementConfigurationSelector.class)
注册
PROXY
JDK
代理通知AutoProxyRegistrar
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry)
注册
org.springframework.aop.config.internalAutoProxyCreator
——InfrastructureAdvisorAutoProxyCreator
优先级判断
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry)
org.springframework.aop.config.internalAutoProxyCreator
设置属性proxyTargetClass
ProxyTransactionManagementConfiguration
注册如下的Bean
transactionAdvisor
——BeanFactoryTransactionAttributeSourceAdvisor
事务通知者TransactionAttributeSource
Advice
——TransactionInterceptor
transactionAttributeSource
——AnnotationTransactionAttributeSource
transactionInterceptor
——TransactionInterceptor
事务方法拦截器TransactionAttributeSource
TransactionManager
ASPECTJ
AspectJ
代理通知AspectJJtaTransactionManagementConfiguration
AspectJTransactionManagementConfiguration