Spring AOP 学习记录2
2021-02-20 15:18
标签:targe 步骤 code 问题 epo tar ESS static put 补充学习一下一些关于Spring AOP的理解 在当前Bean被AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization方法处理的过程中 会需要找到当前Bean可以被应用到的所有advisor. 看代码也知道大致的步骤: 1.findCandidateAdvisors 找到所有的advisor 2.findAdvisorsThatCanApply 过滤出可以使用的advisor 如何找到所有advisor? Creates a Spring Advisor for each AspectJ advice method.
BF中取到所有的BeanName,并遍历.对于每个BeanName,找到对应的Type(Class).再去找它这个类是否有Aspect.class的注解 从中我们可以看出我们如果要使用AOP有什么样的条件: 1.这个Aspect的类应该要被当做Bean.不然BF中里没有这个Bean的定义.不管是在XML里直接定义BeanDifination还是@Component都OK. 2.这个类应该要有@Aspect.不然怎么知道这个是一个aspect呢.(其实还有一种是compiledByAjc(clazz)..没用过.不清楚怎么用) 找到了Aspect的类以后只要提取其中的advisor即可. List classAdvisors = this.advisorFactory.getAdvisors(factory); 大致核心如下: 对于类的每个没有标记@PointCut的方法 找到这个方法上的Aspect注解(@before..@after...@around...).从中提取出pointcut的表达式即可. Advisor = advise(你的asperct类里的方法) + pointcut(表达式) 最后封装成InstantiationModelAwarePointcutAdvisorImpl并返回. 这里没有太多神奇的操作. 找到所有的advisor以后就是判断每个advisor能不能作用到当前的类上. 怎么判断的? 之前是提出了pointcut的expression.那这里使用这个expr去和类比较一下即可. Advisor委托MethodMatcher去做对应的match. 具体调用比较复杂..我也没有仔细去看... 这个问题可能经常会遇到.我相信80%出现的情况是一个操作数据库的service上的方法a上有@Transaction, 然后方法b是个很一般的方法.b会调用a.然后发现事务没生效. Spring AOP 学习记录2 标签:targe 步骤 code 问题 epo tar ESS static put 原文地址:https://www.cnblogs.com/abcwt112/p/12681799.html主题
怎么找到当前Bean可以哪些advisor应用
findCandidateAdvisors
1 /**
2 * Look for AspectJ-annotated aspect beans in the current bean factory,
3 * and return to a list of Spring AOP Advisors representing them.
4 *
1 for (Method method : getAdvisorMethods(aspectClass)) {
2 Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
3 if (advisor != null) {
4 advisors.add(advisor);
5 }
6 }
1 private List
1 @Override
2 @Nullable
3 public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
4 int declarationOrderInAspect, String aspectName) {
5
6 validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
7
8 AspectJExpressionPointcut expressionPointcut = getPointcut(
9 candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
10 if (expressionPointcut == null) {
11 return null;
12 }
13
14 return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
15 this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
16 }
1 @Nullable
2 private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class> candidateAspectClass) {
3 AspectJAnnotation> aspectJAnnotation =
4 AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
5 if (aspectJAnnotation == null) {
6 return null;
7 }
8
9 AspectJExpressionPointcut ajexp =
10 new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class>[0]);
11 ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
12 if (this.beanFactory != null) {
13 ajexp.setBeanFactory(this.beanFactory);
14 }
15 return ajexp;
16 }
1 /**
2 * Find and return the first AspectJ annotation on the given method
3 * (there should only be one anyway...).
4 */
5 @SuppressWarnings("unchecked")
6 @Nullable
7 protected static AspectJAnnotation> findAspectJAnnotationOnMethod(Method method) {
8 for (Class> clazz : ASPECTJ_ANNOTATION_CLASSES) {
9 AspectJAnnotation> foundAnnotation = findAnnotation(method, (Class) clazz);
10 if (foundAnnotation != null) {
11 return foundAnnotation;
12 }
13 }
14 return null;
15 }
1 private static final Class>[] ASPECTJ_ANNOTATION_CLASSES = new Class>[] {
2 Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
findAdvisorsThatCanApply
1 public static boolean canApply(Advisor advisor, Class> targetClass, boolean hasIntroductions) {
2 if (advisor instanceof IntroductionAdvisor) {
3 return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
4 }
5 else if (advisor instanceof PointcutAdvisor) {
6 PointcutAdvisor pca = (PointcutAdvisor) advisor;
7 return canApply(pca.getPointcut(), targetClass, hasIntroductions);
8 }
9 else {
10 // It doesn‘t have a pointcut so we assume it applies.
11 return true;
12 }
13 }
AOP本类方法掉用本类方法不生效咋办