zoukankan      html  css  js  c++  java
  • sping aop 源码分析(-)-- 代理对象的创建过程分析

    测试项目已上传到码云,可以下载:https://gitee.com/yangxioahui/aopdemo.git

    具体如下:

    public interface Calc {
        Integer add(int num1,int num2);
    }
    //目标是对add 方法进行切入 @Component
    public class MyMath implements Calc { public Integer add(int num1,int num2){ return num1+num2; } } @Aspect @Component public class MyAspectJ { @Pointcut(" execution(* com.yang.xiao.hui.aop.MyMath.*(..))") private void pointcut(){} @Before(value = "pointcut()") public void before(JoinPoint joinPoint){ System.out.println("before。。。。。"); } @After(value = "pointcut()") public void after(JoinPoint joinPoint){ System.out.println("after。。。。"); } @AfterReturning(value = "pointcut()") public void afterReturning(){ System.out.println("afterReturning。。。"); } @AfterThrowing(value = "pointcut()") public void afterThrowing(JoinPoint joinPoint){ System.out.println("afterThrowing。。。。"); } @Around(value ="pointcut()") public void around(ProceedingJoinPoint joinPoint){ System.out.println("around-before。。。。"); try { Object proceed = joinPoint.proceed(); System.out.println("around-after_return。。。"); } catch (Throwable throwable) { System.out.println("around-throw。。。"+throwable.getMessage()); } System.out.println("around-after。。。"); } } //测试类 @Configuration @ComponentScan("com.yang.xiao.hui.aop") @EnableAspectJAutoProxy(exposeProxy = true) public class App { public static void main( String[] args ) { ApplicationContext ctx = new AnnotationConfigApplicationContext(App.class); Calc myMath = (Calc)ctx.getBean("myMath"); myMath.add(3,5); System.out.println(ctx.getBean("myMath").getClass()); } }

     启动项目结果:

      至此,测试环境搭建完毕

    原理分析:
    我们要对MyMath 类的add 方法进行前后代理,我们也可以自己实现:

     我们实现的叫静态代理,如果是程序实现的叫动态代理;切入的方式有前置切入,后置切入等,切入点有切入表达式(Pointcut),在java中,一切皆对象,spring将各种切入方式叫做Advice(增强器),如BeforeAdvice,而我们是通过方法切入

    所以又叫MethodBeforeAdvice:

    单有一个Advice 我们并不知道要给哪个类进行切入,因此还需要切入点,于是我们将Advice和切入点Pointcut 结合一起组成一个Advisor:

     例如:DefaultPointcutAdvisor它的构造器:

     一个被切入的类,它的代理类,会有很多个Advisor,那么我们称这个代理类叫做Advised:

     至此,我们知道了advice ,advisor 和advised的三者之间的关系了:
    下面的我们要解决的问题是:1.各种切入方式是如何被封装成advisor的 2 如何知道某个类是否需要被代理 3. 如何创建代理类 4 类被代理后,目标方法是如何执行的:

     先来看一个注解:@EnableAspectJAutoProxy()

    
    

     点击进入该注解:

     

     

     我们继续跟进,看看到底向容器注册的是哪个bean;

     

     

     

     我们再看看注解信息是怎么保存到注册器中的;

     

     小结:@EnableAspectJAutoProxy 注解最终向容器中注入了一个 bean---- AnnotationAwareAspectJAutoProxyCreator,因此我们问题的答案都可以在这个bean找到,那么我们看看其继承体系:

    
    

     可见,AnnotationAwareAspectJAutoProxyCreator是一个beanPostProcessor,也就是后置处理器,会在bean的不同生命周期里其作用:

     因此,这些生命周期里,会进行代理对象的创建:

    我们debug 调试容器创建过程:

     

      省略n步骤:

     

     

     

     

     

    public List<Advisor> buildAspectJAdvisors() {
            List<String> aspectNames = this.aspectBeanNames; //首次进来,这个为null
    
            if (aspectNames == null) {
                synchronized (this) {
                    aspectNames = this.aspectBeanNames;
                    if (aspectNames == null) {
                        List<Advisor> advisors = new ArrayList<>();
                        aspectNames = new ArrayList<>();
                        String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                                this.beanFactory, Object.class, true, false); //容器中获取所有的beanName,因为Object可以代表所有的类型
                        for (String beanName : beanNames) {
                            if (!isEligibleBean(beanName)) { //isEligibleBean(beanName)这个基本返回true
                                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); //获取对应的类型
                            if (beanType == null) {
                                continue;
                            }
                            if (this.advisorFactory.isAspect(beanType)) { //判断类有没@Aspect注解,而我们定义的MyAspectJ是有该注解的
                                aspectNames.add(beanName);//切面类可能有多个,我本次测试写了一个MyAspectJ
                                AspectMetadata amd = new AspectMetadata(beanType, beanName);
                                if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { //如果我们的MyMyAspectJ是单例的话,条件成立,显然,我们的就是单例
                                    MetadataAwareAspectInstanceFactory factory =
                                            new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); //获取一个切面工厂
                                    List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);//这里获取了我们要的advisor,所以稍后要分析
                                    if (this.beanFactory.isSingleton(beanName)) {
                                        this.advisorsCache.put(beanName, classAdvisors); //如果是单例就缓存起来,下次就不用再次获取了
                                    }
                                    else {
                                        this.aspectFactoryCache.put(beanName, factory);//非单例就缓存工厂
                                    }
                                    advisors.addAll(classAdvisors);//收集所有的advisor
                                }
                                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 ArrayList<>();
            for (String aspectName : aspectNames) {
                List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
                if (cachedAdvisors != null) {
                    advisors.addAll(cachedAdvisors); //单例的切面类,从缓存中就可以取到他们所有的advisor
                }
                else {
                    MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
                    advisors.addAll(this.advisorFactory.getAdvisors(factory)); //非单例的切面类,从工厂中去处
                }
            }
            return advisors;
        }

    //通过上面分析:最终会通过调用advisorFactory.getAdvisors(factory)获取到advisor,继续跟进:

    @Override
        public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
            Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //获取切面类,在这里就是我们的com.yang.xiao.hui.aop.MyAspectJ
            String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();//获取类名,这里是myAspectJ
            validate(aspectClass);//这里主要校验切面类的父类有@Aspect注解,如果有,必须是抽象类,其次会校验切面类有没@Aspect注解
    
            // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
            // so that it will only instantiate once.
            MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
                    new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); //将工厂进行包装,让其只会实例化一次
    
            List<Advisor> advisors = new ArrayList<>();
            for (Method method : getAdvisorMethods(aspectClass)) { //通过切面类,获取所有的方法,方法不包含含有@Pointcut注解的方法,因为带有该注解的方法为切入点
                Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); //这里将方法封装成了Advisor,后续会跟踪
                if (advisor != null) { //并不是所有方法,都能封装成advisor的,只有含有@before,@after等注解的方法才会被封装
                    advisors.add(advisor);
                }
            }
    
            // If it's a per target aspect, emit the dummy instantiating aspect.
            if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { //懒加载相关的,会增加一个advisor,显然我们的不是
                Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
                advisors.add(0, instantiationAdvisor);
            }
    
            // Find introduction fields.
            for (Field field : aspectClass.getDeclaredFields()) {  //查询有没哪个字段是有@DeclareParents注解的,我们定义的类没有字段 
                Advisor advisor = getDeclareParentsAdvisor(field);
                if (advisor != null) {
                    advisors.add(advisor);
                }
            }
    
            return advisors;
        }

    根据上面分析,切面类的方法最终转成advisor,是调用了 Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);我们跟进去:

    @Override
        @Nullable
        public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
                int declarationOrderInAspect, String aspectName) {
    
            validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); //校验切面类的父类有没@Aspect注解,如果有,必须是抽象类,其次会校验切面类有没@Aspect注解
    
            AspectJExpressionPointcut expressionPointcut = getPointcut(
                    candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); //里面会校验candidateAdviceMethod方法是否有@Before @After等注解
            if (expressionPointcut == null) {
                return null;
            }
    
            return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
                    this, aspectInstanceFactory, declarationOrderInAspect, aspectName); //这个就是我们要找的advisor,expressionPointcut含有pointcut和advice 
     
    }

    我们分析下: AspectJExpressionPointcut expressionPointcut = getPointcut( candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); 方法:

    @Nullable
        private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
            AspectJAnnotation<?> aspectJAnnotation =
                    AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); //这里是判断有没对应注解
            if (aspectJAnnotation == null) {
                return null;
            }
    
            AspectJExpressionPointcut ajexp =
                    new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
            ajexp.setExpression(aspectJAnnotation.getPointcutExpression()); //这里将@before/@After等注解的切入点表达式存起来了
            if (this.beanFactory != null) {
                ajexp.setBeanFactory(this.beanFactory);
            }
            return ajexp;
        }
    
    
    @Nullable
    protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) { //查询某个方法是否有aspectj相关注解
       for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) { //ASPECTJ_ANNOTATION_CLASSES //相关注解类如下图:
          AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
          if (foundAnnotation != null) {
             return foundAnnotation;
          }
       }
       return null;
    }
    //经过分析,所有的advisor,最终的类型是InstantiationModelAwarePointcutAdvisorImpl 看看起构造器
    public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
                Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
                MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    
            this.declaredPointcut = declaredPointcut; //切入点表达式
            this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); //增强方法所在的类,也就是切入类
            this.methodName = aspectJAdviceMethod.getName(); //增强的方法名@before等注解标注的类
            this.parameterTypes = aspectJAdviceMethod.getParameterTypes();//advice方法的参数类型
            this.aspectJAdviceMethod = aspectJAdviceMethod;//advice方法,@before等注解标注的方法
            this.aspectJAdvisorFactory = aspectJAdvisorFactory; //工厂类
            this.aspectInstanceFactory = aspectInstanceFactory;//工厂类
            this.declarationOrder = declarationOrder;
            this.aspectName = aspectName;//切面类
    
            if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { //切面类如果是懒加载的话,走下面逻辑
                // Static part of the pointcut is a lazy type.
                Pointcut preInstantiationPointcut = Pointcuts.union(
                        aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
    
                // Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
                // If it's not a dynamic pointcut, it may be optimized out
                // by the Spring AOP infrastructure after the first evaluation.
                this.pointcut = new PerTargetInstantiationModelPointcut(
                        this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
                this.lazy = true;
            }
            else {
                // A singleton aspect.
                this.pointcut = this.declaredPointcut; //切入点
                this.lazy = false;
                this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);//创建一个advice
            }
        }

    我们看看advice的创建过程:

    private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
            Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
                    this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
            return (advice != null ? advice : EMPTY_ADVICE);
        }
    @Override
        @Nullable
        public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
                MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    
            Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();//获取切面类
            validate(candidateAspectClass); 再次校验切面类
    
            AspectJAnnotation<?> aspectJAnnotation =
                    AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);//校验增强方法是否含有@before等相关注解
            if (aspectJAnnotation == null) {
                return null;
            }
    
            // If we get here, we know we have an AspectJ method.
            // Check that it's an AspectJ-annotated class
            if (!isAspect(candidateAspectClass)) { //这里又一次校验有没@Aspect注解
                throw new AopConfigException("Advice must be declared inside an aspect type: " +
                        "Offending method '" + candidateAdviceMethod + "' in class [" +
                        candidateAspectClass.getName() + "]");
            }
    
            if (logger.isDebugEnabled()) {
                logger.debug("Found AspectJ method: " + candidateAdviceMethod);
            }
    
            AbstractAspectJAdvice springAdvice;
    
            switch (aspectJAnnotation.getAnnotationType()) { //根据注解的类型创建对应的advice 
                case AtPointcut: //如果是切入点,其实就不用创建advice了
                    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;
        }
    
    

    通过advice的创建过程,我们知道,一个advice主要包含增强的方法,方法参数,以及切入点,而advisor是包含Advice的,并且属性更多,功能更强大

     

     至此,我们的第一个问题解决了:各种切入方式是如何被封装成advisor的?

      小结:AnnotationAwareAspectJAutoProxyCreator这个类实现了InstantiationAwareBeanPostProcessor接口,所以其中有个方法:Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)

    在其他bean创建的过程中,会调用该方法,该方法会去查找容器中所有的advisor,查找的思路是获取所有的Bean的名称,然后通过名称获取bean的类型(此时bean还没实例化,所以取得是类型),之后判断有没@Aspect注解如果有该注解的话,就判断类下面的方法有没Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class 这几个注解,有就将对应的方法封装成advice,进一步封装成advisor

     至此,所有的切入方法都封装成了advisor,存到了一个list集合中,下面分析代理类的创建,也就是我们的MyMath被代理过程:debug调试其创建bean的过程

    前面分析过: AnnotationAwareAspectJAutoProxyCreator 实现BeanPostProcessor接口,该接口有2个方法:

     我们先看看postProcessBeforeInitialization 的代码:

     可见,没做任何逻辑,我们再看看另外一个方法:postProcessAfterInitialization

     所以我们断点在该方法,调试MyMath创建过程:

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {  //在postProcessBeforeInstantiation方法也有创建代理对象逻辑,如果在那个方法创建的代理对象会存到targetSourcedBeans
                return bean;
            }
            if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { //advisedBeans 缓存中已经有该bean,并且不用增强
                return bean;
            }
    //InfrastructureClass 是指Advice,Pointcut,Advisor,AopInfrastructureBean; shouldSkip(bean.getClass(), beanName)指的是beanName以.ORIGINAL” 结尾的
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { postProcessBeforeInstantiation这个方法也有一样的逻辑 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //获取能用在该类上的advisor,逻辑是根据切面表达式来判断,之后会分析 if (specificInterceptors != DO_NOT_PROXY) { //如果获取到的advisor不为空,也就是由advisor可以用在该类上就创建代理对象 this.advisedBeans.put(cacheKey, Boolean.TRUE); //设置缓存,说明该bean的创建需要代理 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); //创建代理对象 this.proxyTypes.put(cacheKey, proxy.getClass());//缓存代理对象的类 return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); //如果没有可用的增强器,就标注上该bean不用创建代理 return bean; }

     //上面要关注的2个方法,一个是如何查找一个类的增强器,也就是advisor,第二个是代理对象的创建:

    先看这个方法:Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
            List<Advisor> candidateAdvisors = findCandidateAdvisors(); //获取所有的advisor,这个在之前已经分析过了
            List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);//拿到所有的advisor,看看哪些能用在指定的bean,下面会跟进分析
            extendAdvisors(eligibleAdvisors); //而外加入了一个advisor: advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
            if (!eligibleAdvisors.isEmpty()) {
                eligibleAdvisors = sortAdvisors(eligibleAdvisors); //排序
            }
            return eligibleAdvisors;
        }
    protected List<Advisor> findAdvisorsThatCanApply(
                List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
    
            ProxyCreationContext.setCurrentProxiedBeanName(beanName);
            try {
                return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); //继续跟进该方法
            }
            finally {
                ProxyCreationContext.setCurrentProxiedBeanName(null);
            }
        }
        public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
            if (candidateAdvisors.isEmpty()) { //如果没有候选的advisor,就不用走下去了
                return candidateAdvisors;
            }
            List<Advisor> eligibleAdvisors = new ArrayList<>();
            for (Advisor candidate : candidateAdvisors) { 
                if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {//前面分析过,我们的advisor类型是:InstantiationModelAwarePointcutAdvisor 所以不会进入下面逻辑
                    eligibleAdvisors.add(candidate);
                }
            }
            boolean hasIntroductions = !eligibleAdvisors.isEmpty();
            for (Advisor candidate : candidateAdvisors) {
                if (candidate instanceof IntroductionAdvisor) {//前面分析过,我们的advisor类型是:InstantiationModelAwarePointcutAdvisor 所以不会进入下面逻辑
                    // already processed
                    continue;
                }
                if (canApply(candidate, clazz, hasIntroductions)) { //最终会到达这里,所以canApply(candidate, clazz, hasIntroductions) 决定了该advisor能否用于指定的class
                    eligibleAdvisors.add(candidate);
                }
            }
            return eligibleAdvisors;
        }
    public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
            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)) { //判断切入点过滤的类型能否跟指定的类匹配,例如切入点表达式指定的是A类型,那么只有A类型才符合
                return false;
            }
    
            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;
            if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
                introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
            }
    
            Set<Class<?>> classes = new LinkedHashSet<>();
            if (!Proxy.isProxyClass(targetClass)) { //如果目标class不是Proxy的子类
                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; //判断是否有方法匹配了,只要有一个方法匹配上切入点表达式,对应的advisor就可以用在目标class上
                    }
                }
            }
    
            return false;
        }

    至此,我们知道了给目标class获取advisor的原理: 获取所有的advisor,然后遍历,根据advisor的切入点表达式Pointcut,校验目标class的方法是否有匹配上advisor的

       接着,我们分析代理对象的创建过程:

    Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); //创建代理对象
    目标bean被封装成了一个SingletonTargetSource   
    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
                @Nullable Object[] specificInterceptors, TargetSource targetSource) {
    
            if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
           //这里给bean的定义设置了一个属性originalTargetClass  AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)
    this.beanFactory, beanName, beanClass); } ProxyFactory proxyFactory = new ProxyFactory();//代理工厂 proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { //@EnableAspectJAutoProxy 注解的proxyTargetClass属性,当为true时,就不支持jdk动态代理,全部使用cglib,默认是false if (shouldProxyTargetClass(beanClass, beanName)) { //判断bean的定义对象的属性preserveTargetClass 是否为true,为true时,只支持cglib proxyFactory.setProxyTargetClass(true); } else {
    //判断beanClass所有的实现接口,排除InitializingBean,AutoCloseable,DisposableBean,Closeable,Aware,是否还有其他接口,是的话,就可以用jdk动态代理 evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors
    = buildAdvisors(beanName, specificInterceptors);//主要的功能是强转,因为specificInterceptors数组的类型是Object proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory);//目前空实现 proxyFactory.setFrozen(this.freezeProxy); //设置是否需要冻结代理相关的配置,false if (advisorsPreFiltered()) { //advisor是否是过滤过的了,根据前面分析,advisor用于指定的bean前,通过切入点表达式过滤过了 proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(getProxyClassLoader()); }
    
    

     //上面只是为需要代理的bean,创建了一个代理工厂,并且代理工厂设置了advisors 和目标bean对象,接下来跟进代理对象创建:

     先分析: createAopProxy()

    public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
        //前面ProxyFactory 设置的目标对象,advisors 都存在AdvisedSupport这里了
        @Override
        public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
         // 源码对 config.isOptimize()解释:optimization will usually mean that advice changes won't take effect after a proxy has been created.
    //config.isOptimize()默认是false,config.isProxyTargetClass这个是@EnableAspectJAutoProxy的属性,为true时,即使目标类实现了接口也用cglib代理
    //hasNoUserSuppliedProxyInterfaces(config) 没有用户提供的接口时,也没法使用jdk动态代理

     
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { //如果目标类就是接口,或者其继承了Proxy类,那就没法使用cglib代理了 return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); //使用cglib代理 } else { return new JdkDynamicAopProxy(config); //使用jdk代理 } }
    ... 省略其他代码
    }

     由于我的是jdk动态代理,执行getProxy后:

     我们看看获取接口的方法:

    static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) { //主要是加上了三个接口SpringProxy,Advised,DecoratingProxy
            Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces(); 
            if (specifiedInterfaces.length == 0) {
                // No user-specified interfaces: check whether target class is an interface.
                Class<?> targetClass = advised.getTargetClass();
                if (targetClass != null) {
                    if (targetClass.isInterface()) {
                        advised.setInterfaces(targetClass);
                    }
                    else if (Proxy.isProxyClass(targetClass)) {
                        advised.setInterfaces(targetClass.getInterfaces());
                    }
                    specifiedInterfaces = advised.getProxiedInterfaces();
                }
            }
            boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
            boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
            boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
            int nonUserIfcCount = 0;
            if (addSpringProxy) {
                nonUserIfcCount++;
            }
            if (addAdvised) {
                nonUserIfcCount++;
            }
            if (addDecoratingProxy) {
                nonUserIfcCount++;
            }
            Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
            System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
            int index = specifiedInterfaces.length;
            if (addSpringProxy) {
                proxiedInterfaces[index] = SpringProxy.class;
                index++;
            }
            if (addAdvised) {
                proxiedInterfaces[index] = Advised.class;
                index++;
            }
            if (addDecoratingProxy) {
                proxiedInterfaces[index] = DecoratingProxy.class;
            }
            return proxiedInterfaces;
        }
    Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); 这个是jdk源码的内容了

    至此,spring创建代理对象的源码分析完毕了,我们看看cglib的getProxy方法:

    @Override
        public Object getProxy(@Nullable ClassLoader classLoader) {
            if (logger.isTraceEnabled()) {
                logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
            }
    
            try {
                Class<?> rootClass = this.advised.getTargetClass(); //因为cglib使用的继承方式,所以目标类就是父类
                Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
    
                Class<?> proxySuperClass = rootClass;
                if (ClassUtils.isCglibProxyClass(rootClass)) { //判断目标类是否已经是cglib的代理类了,cglib的代理类,beanName是以"$$" 结尾的
                    proxySuperClass = rootClass.getSuperclass(); 如果是的话,就代理目标类的父类
                    Class<?>[] additionalInterfaces = rootClass.getInterfaces();
                    for (Class<?> additionalInterface : additionalInterfaces) {
                        this.advised.addInterface(additionalInterface);
                    }
                }
    
                // Validate the class, writing log messages as necessary. 做一些日志打印
                validateClassIfNecessary(proxySuperClass, classLoader);
    
                // Configure CGLIB Enhancer...
                Enhancer enhancer = createEnhancer(); //cglib的创建器,相当于jdk动态代理的代理工厂Proxy
                if (classLoader != null) {
                    enhancer.setClassLoader(classLoader); //设置类加载器
                    if (classLoader instanceof SmartClassLoader &&
                            ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                        enhancer.setUseCache(false);
                    }
                }
                enhancer.setSuperclass(proxySuperClass); //设置需要代理的类
                enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); //跟jdk代理一样,这里也会新增三个接口SpringProxy,Advised,DecoratingProxy
                enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);//cglib代理对象的命名策略,会加上"$$" 和 BySpringCGLIB 这些字符
                enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
    
                Callback[] callbacks = getCallbacks(rootClass);
                Class<?>[] types = new Class<?>[callbacks.length];
                for (int x = 0; x < types.length; x++) {
                    types[x] = callbacks[x].getClass();
                }
                // fixedInterceptorMap only populated at this point, after getCallbacks call above
                enhancer.setCallbackFilter(new ProxyCallbackFilter(
                        this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
                enhancer.setCallbackTypes(types);
    
                // Generate the proxy class and create a proxy instance.
                return createProxyClassAndInstance(enhancer, callbacks);//最终会调用该方法创建一个代理对象
            }
            catch (CodeGenerationException | IllegalArgumentException ex) {
                throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
                        ": Common causes of this problem include using a final class or a non-visible class",
                        ex);
            }
            catch (Throwable ex) {
                // TargetSource.getTarget() failed
                throw new AopConfigException("Unexpected AOP exception", ex);
            }
        }
    @Override
        protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
            Class<?> proxyClass = enhancer.createClass(); //创建出代理类
            Object proxyInstance = null;
    
            if (objenesis.isWorthTrying()) {
                try {
                    proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());  //创建代理实例
                }
                catch (Throwable ex) {
                    logger.debug("Unable to instantiate proxy using Objenesis, " +
                            "falling back to regular proxy construction", ex);
                }
            }
    
            if (proxyInstance == null) {
                // Regular instantiation via default constructor...
                try {
                    Constructor<?> ctor = (this.constructorArgs != null ?
                            proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
                            proxyClass.getDeclaredConstructor());
                    ReflectionUtils.makeAccessible(ctor);
                    proxyInstance = (this.constructorArgs != null ?
                            ctor.newInstance(this.constructorArgs) : ctor.newInstance()); //通过构造器创建代理实例
                }
                catch (Throwable ex) {
                    throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
                            "and regular proxy instantiation via default constructor fails as well", ex);
                }
            }
    
            ((Factory) proxyInstance).setCallbacks(callbacks);
            return proxyInstance;
        }

     我们可以输出代理类的字节码,设置一个属性:System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

     执行后,在类路径可以看到:

     找到我们的目标类:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package com.sun.proxy;
    
    import com.yang.xiao.hui.aop.Calc;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.lang.reflect.UndeclaredThrowableException;
    import org.aopalliance.aop.Advice;
    import org.springframework.aop.Advisor;
    import org.springframework.aop.SpringProxy;
    import org.springframework.aop.TargetSource;
    import org.springframework.aop.framework.Advised;
    import org.springframework.aop.framework.AopConfigException;
    import org.springframework.core.DecoratingProxy;
    //代理对象的所有方法的调用最终都会交给InvocationHandler 的invoke方法执行
    public final class $Proxy22 extends Proxy implements Calc, SpringProxy, Advised, DecoratingProxy { // SpringProxy, Advised, DecoratingProxy 这三个接口是后面加上的,前面分析过了
        private static Method m1;
        private static Method m9;
        private static Method m14;
        private static Method m13;
        private static Method m19;
        private static Method m24;
        private static Method m4;
        private static Method m8;
        private static Method m17;
        private static Method m18;
        private static Method m0;
        private static Method m23;
        private static Method m16;
        private static Method m11;
        private static Method m7;
        private static Method m2;
        private static Method m26;
        private static Method m15;
        private static Method m27;
        private static Method m20;
        private static Method m5;
        private static Method m6;
        private static Method m21;
        private static Method m10;
        private static Method m3;
        private static Method m25;
        private static Method m12;
        private static Method m22;
    
        public $Proxy22(InvocationHandler var1) throws  {
            super(var1);
        }
    
        public final boolean equals(Object var1) throws  {
            try {
                return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final boolean isExposeProxy() throws  {
            try {
                return (Boolean)super.h.invoke(this, m9, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final void addAdvisor(Advisor var1) throws AopConfigException {
            try {
                super.h.invoke(this, m14, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final boolean isProxyTargetClass() throws  {
            try {
                return (Boolean)super.h.invoke(this, m13, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final void removeAdvisor(int var1) throws AopConfigException {
            try {
                super.h.invoke(this, m19, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final Class[] getProxiedInterfaces() throws  {
            try {
                return (Class[])super.h.invoke(this, m24, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final int indexOf(Advisor var1) throws  {
            try {
                return (Integer)super.h.invoke(this, m4, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final TargetSource getTargetSource() throws  {
            try {
                return (TargetSource)super.h.invoke(this, m8, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final void addAdvice(int var1, Advice var2) throws AopConfigException {
            try {
                super.h.invoke(this, m17, new Object[]{var1, var2});
            } catch (RuntimeException | Error var4) {
                throw var4;
            } catch (Throwable var5) {
                throw new UndeclaredThrowableException(var5);
            }
        }
    
        public final void addAdvice(Advice var1) throws AopConfigException {
            try {
                super.h.invoke(this, m18, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final int hashCode() throws  {
            try {
                return (Integer)super.h.invoke(this, m0, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final boolean isInterfaceProxied(Class var1) throws  {
            try {
                return (Boolean)super.h.invoke(this, m23, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final boolean removeAdvice(Advice var1) throws  {
            try {
                return (Boolean)super.h.invoke(this, m16, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final void setExposeProxy(boolean var1) throws  {
            try {
                super.h.invoke(this, m11, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final void setTargetSource(TargetSource var1) throws  {
            try {
                super.h.invoke(this, m7, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final String toString() throws  {
            try {
                return (String)super.h.invoke(this, m2, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final Class getTargetClass() throws  {
            try {
                return (Class)super.h.invoke(this, m26, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final void addAdvisor(int var1, Advisor var2) throws AopConfigException {
            try {
                super.h.invoke(this, m15, new Object[]{var1, var2});
            } catch (RuntimeException | Error var4) {
                throw var4;
            } catch (Throwable var5) {
                throw new UndeclaredThrowableException(var5);
            }
        }
    
        public final Class getDecoratedClass() throws  {
            try {
                return (Class)super.h.invoke(this, m27, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final boolean removeAdvisor(Advisor var1) throws  {
            try {
                return (Boolean)super.h.invoke(this, m20, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final int indexOf(Advice var1) throws  {
            try {
                return (Integer)super.h.invoke(this, m5, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final boolean isFrozen() throws  {
            try {
                return (Boolean)super.h.invoke(this, m6, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final boolean replaceAdvisor(Advisor var1, Advisor var2) throws AopConfigException {
            try {
                return (Boolean)super.h.invoke(this, m21, new Object[]{var1, var2});
            } catch (RuntimeException | Error var4) {
                throw var4;
            } catch (Throwable var5) {
                throw new UndeclaredThrowableException(var5);
            }
        }
    
        public final void setPreFiltered(boolean var1) throws  {
            try {
                super.h.invoke(this, m10, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final Integer add(int var1, int var2) throws  {
            try {
                return (Integer)super.h.invoke(this, m3, new Object[]{var1, var2});
            } catch (RuntimeException | Error var4) {
                throw var4;
            } catch (Throwable var5) {
                throw new UndeclaredThrowableException(var5);
            }
        }
    
        public final String toProxyConfigString() throws  {
            try {
                return (String)super.h.invoke(this, m25, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final Advisor[] getAdvisors() throws  {
            try {
                return (Advisor[])super.h.invoke(this, m12, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final boolean isPreFiltered() throws  {
            try {
                return (Boolean)super.h.invoke(this, m22, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        static {
            try {
                m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
                m9 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isExposeProxy");
                m14 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvisor", Class.forName("org.springframework.aop.Advisor"));
                m13 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isProxyTargetClass");
                m19 = Class.forName("org.springframework.aop.framework.Advised").getMethod("removeAdvisor", Integer.TYPE);
                m24 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getProxiedInterfaces");
                m4 = Class.forName("org.springframework.aop.framework.Advised").getMethod("indexOf", Class.forName("org.springframework.aop.Advisor"));
                m8 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getTargetSource");
                m17 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvice", Integer.TYPE, Class.forName("org.aopalliance.aop.Advice"));
                m18 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvice", Class.forName("org.aopalliance.aop.Advice"));
                m0 = Class.forName("java.lang.Object").getMethod("hashCode");
                m23 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isInterfaceProxied", Class.forName("java.lang.Class"));
                m16 = Class.forName("org.springframework.aop.framework.Advised").getMethod("removeAdvice", Class.forName("org.aopalliance.aop.Advice"));
                m11 = Class.forName("org.springframework.aop.framework.Advised").getMethod("setExposeProxy", Boolean.TYPE);
                m7 = Class.forName("org.springframework.aop.framework.Advised").getMethod("setTargetSource", Class.forName("org.springframework.aop.TargetSource"));
                m2 = Class.forName("java.lang.Object").getMethod("toString");
                m26 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getTargetClass");
                m15 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvisor", Integer.TYPE, Class.forName("org.springframework.aop.Advisor"));
                m27 = Class.forName("org.springframework.core.DecoratingProxy").getMethod("getDecoratedClass");
                m20 = Class.forName("org.springframework.aop.framework.Advised").getMethod("removeAdvisor", Class.forName("org.springframework.aop.Advisor"));
                m5 = Class.forName("org.springframework.aop.framework.Advised").getMethod("indexOf", Class.forName("org.aopalliance.aop.Advice"));
                m6 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isFrozen");
                m21 = Class.forName("org.springframework.aop.framework.Advised").getMethod("replaceAdvisor", Class.forName("org.springframework.aop.Advisor"), Class.forName("org.springframework.aop.Advisor"));
                m10 = Class.forName("org.springframework.aop.framework.Advised").getMethod("setPreFiltered", Boolean.TYPE);
                m3 = Class.forName("com.yang.xiao.hui.aop.Calc").getMethod("add", Integer.TYPE, Integer.TYPE);
                m25 = Class.forName("org.springframework.aop.framework.Advised").getMethod("toProxyConfigString");
                m12 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getAdvisors");
                m22 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isPreFiltered");
            } catch (NoSuchMethodException var2) {
                throw new NoSuchMethodError(var2.getMessage());
            } catch (ClassNotFoundException var3) {
                throw new NoClassDefFoundError(var3.getMessage());
            }
        }
    }

    //通过分析,我们知道,jdk动态代理类的所有方法,都会交给//代理对象的所有方法的调用最终都会交给InvocationHandler 的invoke方法执行,那么这个InvocationHandler 又是哪里来的呢,我们回到jdk动态代理创建过程:

     

     因此代理类的方法会被JdkDynamicAopProxy 的invoke 拦截,而JdkDynamicAopProxy有个属性:AdvisedSupport 该对象拥有被代理对象和advisors,因此可以进行前后拦截了,而AdvisedSupport 是什么时候传入的呢?

     至此,哪个类会被代理,以及如何代理,分析完毕,下篇博客,我们会分析,代理方法的执行流程

     
     
    
    
    
    
    
    
    
    
    
    
    
    
    
    

     



  • 相关阅读:
    NSString常用方法
    iOS8 【xcode6中添加pch全局引用文件】
    Size Classes with Xcode 6
    推荐学习网站
    Objective C类方法load和initialize的区别
    iOS开发中,单元测试的好处!
    iOS 9.0中UIAlertController的用法。
    iOS 9.0 数组中所有对象共同执行方法的接口不可用
    Xcode 7.0以后 iOS 9.0以后 最新百度地图 详细使用
    iOS9适配关于URL Schemes
  • 原文地址:https://www.cnblogs.com/yangxiaohui227/p/13266014.html
Copyright © 2011-2022 走看看