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
<aop:aspectj-autoproxy />
proxyTargetClass对应xml中属性proxy-target-class,是否启用CGLIBexposeProxy对应xml中属性expose-proxy,是否暴露代理,设置为true的时候,可以通过AopContext.currentProxy()获取代理实例(通过ThreadLocal进行实现的)
@Aspect
切面,横切多个类的关系的模块化
@Aspect
@Component
public class LogAspect {
}
相当于xml中
<aop:config>
<aop:aspect id="logAspect" ref="logAspectBean">
</aop:config>
<bean id="logAspectBean" class="top.felixfly.aop.apesct.LogAspect"></bean>
@Pointcut
切点,执行方法的切点
@Pointcut("execution(* top.felixfly.aop.service.*Service.*(..))")
public void servicePoint() {
}
相当于xml中
<aop:config>
<aop:pointcut id="servicePoint"
expression="execution(* top.felixfly.aop.service.*Service.*(..))"/>
</aop:config>
切入点表达式
-
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包以及子包的所有类的方法
-
withinwithin(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
在切点的方法之前执行方法
@Before("servicePoint()")
public void before(JoinPoint joinPoint) {
System.out.println("before。。。。。");
}
相当于xml中
<aop:config>
<aop:aspect id="logAspect" ref="logAspect">
<aop:pointcut id="servicePoint"
expression="execution(* top.felixfly.aop.service.*Service.*(..))"/>
<aop:before pointcut-ref="servicePoint" method="before"/>
</aop:aspect>
</aop:config>
@AfterReturning
在切点的方法执行返回执行
@AfterReturning(value="servicePoint()",returing="object")
public void afterReturning(JoinPoint joinPoint,Object object) {
System.out.println("afterReturning。。。。。");
}
相当于xml中
<aop:config>
<aop:aspect id="logAspect" ref="logAspect">
<aop:pointcut id="servicePoint"
expression="execution(* top.felixfly.aop.service.*Service.*(..))"/>
<aop:after-returning pointcut-ref="servicePoint" method="afterReturning" returning="object" />
</aop:aspect>
</aop:config>
@AfterThrowing
在切点的方法执行抛出异常执行
@AfterThrowing(value = "servicePoint()", throwing = "ex")
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
System.out.println("afterThrowing。。。。。" + ex);
}
相对于xml中
<aop:config>
<aop:aspect id="logAspect" ref="logAspect">
<aop:pointcut id="servicePoint"
expression="execution(* top.felixfly.aop.service.*Service.*(..))"/>
<aop:after-throwing pointcut-ref="servicePoint" method="afterThrowing" throwing="ex" />
</aop:aspect>
</aop:config>
@After
在切点方法执行之后执行,也就是在@AfterReturning或者@AfterThrowing之前执行
@After("servicePoint()")
public void after(JoinPoint joinPoint) {
System.out.println("after。。。。。");
}
相当于xml中
<aop:config>
<aop:aspect id="logAspect" ref="logAspect">
<aop:pointcut id="servicePoint"
expression="execution(* top.felixfly.aop.service.*Service.*(..))"/>
<aop:after pointcut-ref="servicePoint" method="after" />
</aop:aspect>
</aop:config>
@Around
在切点方法执 行前后执行
@Around(value = "servicePoint()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 执行目标方法之前,在@Before方法之前执行
System.out.println("around before。。。。。" );
// 执行目标方法
Object retVal = joinPoint.proceed(joinPoint.getArgs());
// 执行目标方法之后,@After之前执行
System.out.println("around after。。。。。" );
return retVal;
}
相当于xml中
<aop:config>
<aop:aspect id="logAspect" ref="logAspect">
<aop:pointcut id="servicePoint"
expression="execution(* top.felixfly.aop.service.*Service.*(..))"/>
<aop:around pointcut-ref="servicePoint" method="around" />
</aop:aspect>
</aop:config>
AOP的执行顺序
正常执行流程:@Around -> @Before -> @After -> @AfterReturning
异常执行流程:@Around -> @Before -> @After -> @AfterThrowing
切面的主要接口
PointCut 切入点
ClassFilter类的过滤器MethodMatcher方法的匹配器
Advice 通知
BeforeAdvice前置通知AfterAdvice后置通知AfterReturningAdvice执行返回通知ThrowsAdvice异常通知
MethodInterceptor 方法的拦截器(继承Advice)
MethodBeforeAdviceInterceptor方法前置拦截器AspectJAroundAdviceApectJ环绕拦截器AspectJAfterAdviceApectJ后置拦截器AfterReturningAdviceInterceptor后置返回拦截器AspectJAfterThrowingAdvice后置异常拦截器
Advisor 通知器
Advice通知
PointcutAdvisor 切入点通知器(继承Advisor)
Pointcut切入点
动态代理的主要接口
AopProxy Aop动态代理
JdkDynamicAopProxyJdk动态代理CglibAopProxyCglib动态代理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
实现主要接口
BeanFactoryAwareBeanFactory回调接口InstantiationAwareBeanPostProcessor实例化执行的接口BeanPostProcessorBean后置处理器