spring中aop的源码解析(三)
我们继续查看AbstractAspectJAutoProxyCreator中的wrapIfNecessary方法
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
这里是获取通知
protected Object[] getAdvicesAndAdvisorsForBean( Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { //获取可用的Advisor列表 List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); }
上面方法很简单讲任务委派到findEligibleAdvisors方法上面去。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { //获取所有候选Advisor列表 List<Advisor> candidateAdvisors = findCandidateAdvisors(); //从候选Advisor列表中找出那些能够适用于该类 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { //对Advisor进行排序这里排序设计到Order eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
下面我们先从获取所有候选Advisor
protected List<Advisor> findCandidateAdvisors() { //网上说这里是从xml配置文件中获取候选的advisor列表 List<Advisor> advisors = super.findCandidateAdvisors(); //这里是从所有扫描加载进来的类中获取候选advisor列表 if (this.aspectJAdvisorsBuilder != null) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; }
由于现在项目基本不用xml了加载bean我们就不进入分析直接看下面
BeanFactoryAspectJAdvisorsBuilder下面方法
public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; if (aspectNames == null) { synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List<Advisor> advisors = new LinkedList<>(); aspectNames = new LinkedList<>(); //这里获取所有加载到spring容器中的对象名称 String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); for (String beanName : beanNames) { //判断是否为有效的bean if (!isEligibleBean(beanName)) { continue; } //根据名称获取类对象 Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } //如果类对象上面存在@Aspect注解 if (this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName); //创建Aspect元数据 AspectMetadata amd = new AspectMetadata(beanType, beanName); //如果类时单例 if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { //创建元数据aop实例化工厂 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 { // Per target or per this. if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } this.aspectBeanNames = aspectNames; return advisors; } } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } List<Advisor> advisors = new LinkedList<>(); for (String aspectName : aspectNames) { List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName); if (cachedAdvisors != null) { advisors.addAll(cachedAdvisors); } else { MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } return advisors; }
我们重点分析ReflectiveAspectJAdvisorFactory 上面的getAdvisors
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //获取工厂上面保存的aop类对象 Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //获取工厂类上面保存aop类的名称 String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); validate(aspectClass); MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new LinkedList<>(); //这里是整个方法的核心 获取aop类上面所有的方法一次遍历获取上面的通知 for (Method method : getAdvisorMethods(aspectClass)) { Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } // If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } // Find introduction fields. for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; }
我们看下获取aop类型上面所有的方法的函数
private List<Method> getAdvisorMethods(Class<?> aspectClass) { final List<Method> methods = new LinkedList<>(); ReflectionUtils.doWithMethods(aspectClass, method -> { //这里就是获取被@Aspect注解修饰类上面的所有方法去掉Pointcut注解修饰的方法 if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) { methods.add(method); } }); methods.sort(METHOD_COMPARATOR); return methods; }
下面我们看下根据类对象和方法对象获取通知的方法
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); //这里更加类对象和方法获取上面注解封装为AspectJExpressionPointcut对象 AspectJExpressionPointcut expressionPointcut = getPointcut( candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); if (expressionPointcut == null) { return null; } //封装成InstantionModelAwarePointcutAdvisorImpl return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); }
下面我们进一步进入到封装成AspectJExpressionPointcut方法里面去
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) { //从候选方法上面获取AspectAnnotation注解 AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } //封装为AspectJExpressionPointcut对象 AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]); //设置pointcut字符串表达式 ajexp.setExpression(aspectJAnnotation.getPointcutExpression()); if (this.beanFactory != null) { ajexp.setBeanFactory(this.beanFactory); } return ajexp; }
我们再进入到findAspectJAnnotationOnMethod方法里面去
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) { Class<?>[] classesToLookFor = new Class<?>[] { Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class}; for (Class<?> c : classesToLookFor) { AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c); if (foundAnnotation != null) { return foundAnnotation; } } return null; }
上面就是在获取方法上面含有Before,Aroud,After,AfterReturning,AfterThrowing,Pointcut方法