定义案例
@Component
@Aspect
@Slf4j
public class SpringLearnAop {
@Pointcut("execution(* com.example.springcorelearn.answer..*(..))")
public void definitionPointCut() {
}
@AfterReturning("definitionPointCut()")
public void afterReturningProcess() {
log.info("结束了。。。。");
}
@After("definitionPointCut()")
public void afterProcess() {
log.info("结束了。。。。");
}
@AfterThrowing
public void afterThrowing(){
log.info("异常错误");
}
@Before("definitionPointCut()")
public void beforeProcess() {
log.info("想到我了");
}
@Around("definitionPointCut()")
public Object around(ProceedingJoinPoint joinPoint){
log.info("around start....");
try {
return joinPoint.proceed();
} catch (Throwable e) {
throw new RuntimeException(e);
} finally {
log.info("around end....");
}
}
}
元数据注解定义
连接点:PointCut
增强通知
Around
Befroe
After
AfterReturning
AfterThrowing
工具类
BeanFactoryAspectJAdvisorsBuilder
ReflectiveAspectJAdvisorFactory
重点成员变量
adviceMethodComparator
源码
// Note: although @After is ordered before @AfterReturning and @AfterThrowing,
// an @After advice method will actually be invoked after @AfterReturning and
// @AfterThrowing methods due to the fact that AspectJAfterAdvice.invoke(MethodInvocation)
// invokes proceed() in a `try` block and only invokes the @After advice method
// in a corresponding `finally` block.
Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
new InstanceComparator<>(
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
(Converter<Method, Annotation>) method -> {
AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
return (ann != null ? ann.getAnnotation() : null);
});
Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
分析
保证增强通知元数据方法按顺序排序
Around
Before
After
AfterReturning
AfterThrowing
重点方法
getAdvisors
获得切面配置类的增强通知方法。并排序。
增强通知类
AbstractAspectJAdvice
所有的Advice类都是继承了该抽象类。
重点方法
invokeAdviceMethodWithGivenArgs
源码
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
//执行元数据配置通知方法
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
}
AspectJAroundAdvice
重点实现了MethodInvocation接口
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
return invokeAdviceMethod(pjp, jpm, null, null);
}
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("Mismatch on arguments to advice method [" +
this.aspectJAdviceMethod + "]; pointcut expression [" +
this.pointcut.getPointcutExpression() + "]", ex);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
AspectJMethodBeforeAdvice
重点没有实现MethodInvocation接口
源码
@Override
public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
AsepctJAfterAdvice
重点其实现了MethodInvocation接口
源码
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
分析
使用 try finally 语句。保证invokeAdviceMethod方法一定会执行并且最后执行。
AspectJAfterReturningAdvice
重点没有实现MethodInvocation接口
源码
@Override
public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable {
if (shouldInvokeOnReturnValueOf(method, returnValue)) {
invokeAdviceMethod(getJoinPointMatch(), returnValue, null);
}
}
AspectJAfterThrowingAdvice
重点其实现了MethodInvocation接口
源码
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
分析
重新其父类的invoke方法。捕获catch异常,执行父类的invokeAdviceMethod
AdviceAdpater
适配转化成MethodInterceptor
由于AsepctJAroundAdvice、AsepctJAfterAdvice还有AspectJAfterThrowingAdvice已经实现了MethodInterceptor接口不需要再做适配
MethodBeforeAdviceAdapter
AfterReturningAdeviceAdapter
ThrowingAdapter
AdvisorAdapterRegistry
DefaultAdvisorAdapterRegistry
GlobalAdvisorAdpatorRegistry
MethodMatcher
方法匹配器
AspectJExpressionPointcut 连接点拦截
MethodInterceptor
AsepctJAroundAdvice和AsepctJAfterAdvice已经实现了MethodInterceptor接口
MethodBeforeAdviceInterceptor
源码
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
分析
最容易理解。回调执行前
AfterReturningAdviceInterceptor
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
ThrowsAdviceInterceptor
ReflectiveMethodInvocation
重点方法
proceed
使用责任链模式调用切面方法。
inovkeJoinPoint
执行连接点方法
AopProxy
CglibAopProxy
JdkDynamicAopProxy
AnnotationAwareAspectJAutoProxyCreator
重点方法
buildAspectJAdvisors 查询切面配置类和收集切面信息。
findCandidateAdvisors 查找可用的切面
实例化前处理器
AbstractAutoProxyCreator#postProcessBeforeInstantiation
查找切面元数据配置类
解决切面元数据配置类并将增强通知转化成AbstractAspectJAdvice子类。
包装成InstantiationModelAwarePointcutAdvisorImpl将增强通知保存到BeanFactoryAspectJAdvisorsBuilder.aspectJFactoryCache.aspectJFactoryCache
InstantiationModelAwarePointcutAdvisorImpl 类图
说明其实现了PointcutAdvisors接口。
![](https://i-blog.csdnimg.cn/blog_migrate/5036a15a392f028f9d7707ca68afabc7.png)
初始化后处理器
AbstractAutoProxyCreator#postProcessAfterInitialization
核心逻辑是:创建代理若匹配条件。 AbstractAutoProxyCreator#wrapIfNecessary
匹配条件
AbstractAdvisorAutoProxyCreator#findCandidate
实例前处理器已经调用过该方法。查找可用切面最终保存到BeanFactoryAspectJAdvisorBuilder.aspectJFactoryCache
AopUtils#findAdvisorsThatCanApply
遍历BeanFactoryAspectJAdvisorsBuilder.aspectJFactoryCache.aspectJFactoryCache
并验证切面是否是PointcutAdvisor子类。并且检查切面是否可以应用在目标类的方法上。
源码
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
for (Advisor candidate : candidateAdvisors) {
//由于candidate 都是PointcutAdvior子类,所以不会走这个逻辑
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
//进入这个分支
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
//由于candidate 都是PointcutAdvior子类,所以不会走这个逻辑
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
//methodMatcher 是AspectJExpressionPointcut类型。
MethodMatcher methodMatcher = pc.getMethodMatcher();
//不会走这个条件分支
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
//由于AspectJExpressionPointcut是IntroductionAwareMethodMatcher子类,会走个分支。
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
创建代理
代理工厂 ProxyFactory
createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
ProxyFactory类图
![](https://i-blog.csdnimg.cn/blog_migrate/5f697d830a0e33a443663fa1a7043357.png)
创建代理 AopFactory
getAopProxyFactory().createAopProxy(this);
createAopProxy
DefaultAopProxyFactory.createAopProxy
若proxy-target-class =true 使用CglibAopFactory否则使用JdkDynamicAopFactory
执行代理方法
JdkDynamicAopFactory#invoke
源码
private final AdvisedSupport advised;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// We need to create a method invocation...
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
分析
看getInterceptorsAndDynamicInterceptionAdvice顾名思义获取切面增强通知调用链。
调用ReflectiveMethodInvocation.proceed 执行。
AdvisedSupport#getInterceptorAndDynamicInterceptionAdvice
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
//核心代码,往下看
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
//读取切面适配器注册中心实例
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
//方法匹配器
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
//是否能连接这个方法
match = mm.matches(method, actualClass);
//将增强通知转化成方法拦截器
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (match) {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
//... 删除部分代码。
//由于Advisor 都是PointCutAdvisor实现类
}
return interceptorList;
}
ReflectiveMethodInvocation#process
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//当责任链执行完,调用连接点代码。
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//删除无关代码
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
AnnotationAwareApsectJAutoProxyCreator#findCandidateAdvisors
@Override
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvsiors
查询切面配置类缓存到内部advisorsCache
private final Map<String, MetadataAwareAspectInstanceFactory> aspectFactoryCache = new ConcurrentHashMap<>();
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
//遍历所有的bean。
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
//验证是否是Aspect配置类
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
//...
}
}
}
}
}
}
//.....
return advisors;
}
ReflectiveAspectJAdvisorsFactory.getAdvice
将注解转化成增强通知类Advice
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}