zoukankan      html  css  js  c++  java
  • spring源码解析三( aop)

    主要分三块

    1、aop增强器的解析

    2、代理对象的生成

    3、代理对象方法的调用

    一、aop增强器的解析

    1、首先EnableAspectJAutoProxy从入手

    @Configuration
    @EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
    //EnableAspectJAutoProxy表示开启aop,导入aop处理器
    //exposeProxy 表示暴露对象,设置为true后,可以通过AopContext.currentProxy()获取到代理对象
    //proxyTargetClass  设置为true,表示使用cglib代理
    public class MainConfig {
    
        @Bean
        public Calculate XXX() {
            return new XXX();
        }
    }

    点击进入EnableAspectJAutoProxy

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(AspectJAutoProxyRegistrar.class)
    public @interface EnableAspectJAutoProxy {
    
        boolean proxyTargetClass() default false;
      
        boolean exposeProxy() default false;
    
    }

    import导入了AspectJAutoProxyRegistrar组件,之前说过import导入组件的方式 IOC导入容器的方式,AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar ,可以注册bean定义

    class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    
     
        @Override
        public void registerBeanDefinitions(
                AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            //注册aop后置处理器AnnotationAwareAspectJAutoProxyCreator
            AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
            //获取EnableAspectJAutoProxy配置的属性
            AnnotationAttributes enableAspectJAutoProxy =
                    AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }

    2、注册 AnnotationAwareAspectJAutoProxyCreator

    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
            return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
        }
    
    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
            return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
        }
    
    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
            //判断是否包含该类,包含的话判断已经存在的和当前的优先级,如果当前的优先级高,就用当前的 
            if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
                BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
                if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
                    int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                    int requiredPriority = findPriorityForClass(cls);
                    if (currentPriority < requiredPriority) {
                        apcDefinition.setBeanClassName(cls.getName());
                    }
                }
                return null;
            }
            //注册AnnotationAwareAspectJAutoProxyCreator
            RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
            beanDefinition.setSource(source);
            beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
            beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
            return beanDefinition;
        }

    注册了AnnotationAwareAspectJAutoProxyCreator的bean定义

     可以看到AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor和InstantiationAwareBeanPostProcessor ,前面的文章中Spring后置处理器中有介绍InstantiationAwareBeanPostProcessor, 

    geBean源码中,我们可以发现Object bean = resolveBeforeInstantiation(beanName, mbdToUse);,这里有调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法。

    3、AnnotationAwareAspectJAutoProxyCreator.postProcessBeforeInstantiation()

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            Object cacheKey = this.getCacheKey(beanClass, beanName);
            // 判断TargetSource缓存中是否包含当前bean,如果不包含,则判断当前bean是否是已经被代理的bean,
            // 如果代理过,则不对当前传入的bean进行处理,如果没代理过,则判断当前bean是否为系统bean,或者是
            // 切面逻辑不会包含的bean,如果是,则将当前bean缓存到advisedBeans中,否则继续往下执行。
            // 经过这一步的处理之后,只有在TargetSource中没有进行缓存,并且应该被切面逻辑环绕,但是目前还未
            // 生成代理对象的bean才会通过此方法。
            if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
                if (this.advisedBeans.containsKey(cacheKey)) {
                    return null;
                }
                //若是基础的class ||或者是否应该跳过 shouldSkip直接返回false
                //是不是Advice PointCut Advisor AopInfrastructureBean Aspect满足任意返回ture
                if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
                    ////把cacheKey 存放在advisedBeans中
                    this.advisedBeans.put(cacheKey, Boolean.FALSE);
                    return null;
                }
            }
            // 获取封装当前bean的TargetSource对象,如果不存在,则直接退出当前方法,否则从TargetSource
    // 如果没有实现这个接口,正常情况下不会有,暂时也没接触过,不知道这个接口用来干嘛的
    // 获取当前bean对象,并且判断是否需要将切面逻辑应用在当前bean上。 if (beanName != null) { TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName); if (targetSource != null) { this.targetSourcedBeans.add(beanName); // 获取能够应用当前bean的切面逻辑 Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); // 根据切面逻辑为当前bean生成代理对象 Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } } return null; }

    4、shouldSkip()

    protected boolean shouldSkip(Class<?> beanClass, String beanName) {
            // TODO: Consider optimization by caching the list of the aspect names
            //找到候选的增强器
            //主要的逻辑就在这,解析所有的bean定义,获取Advisor放入缓存中去,在真正创建代理的时候可以直接从缓存中获取
        List<Advisor> candidateAdvisors = findCandidateAdvisors(); 

    for (Advisor advisor : candidateAdvisors) { //判断是不是AspectJPointcutAdvisor的实例 if (advisor instanceof AspectJPointcutAdvisor) { if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) { return true; } } } return super.shouldSkip(beanClass, beanName); } protected boolean shouldSkip(Class<?> beanClass, String beanName) { return false; }

    5、findCandidateAdvisors()

    protected List<Advisor> findCandidateAdvisors() {
            // Add all the Spring advisors found according to superclass rules.
    //这里返回的是实现Advisor接口的类,我们熟悉的配置mybatis事务的时候有见过advisor
    List<Advisor> advisors = super.findCandidateAdvisors(); // Build Advisors for all AspectJ aspects in the bean factory.
    //配置的切面Aspect是在这里创建增强器的 advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); return advisors; } 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<Advisor>(); aspectNames = new LinkedList<String>();
    //找到所有被spring管理的类 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); 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);
    //在这里生成advisors 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<Advisor>(); 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; }

    6、getAdvisors()

    public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
            //获取切面类
            Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
            //获取切面名称
            String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
            validate(aspectClass);
    
            // 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<Advisor>();
            //获取切面类排除@PointCut标志的所有方法
            for (Method method : getAdvisorMethods(aspectClass)) {
                //每一个方法都调用getAdvisor方法来获取增强器
                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;
        }
    
    
    public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
          int declarationOrderInAspect, String aspectName) {
    
       validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
       //获取aspectj的切点表达式
       AspectJExpressionPointcut expressionPointcut = getPointcut(
             candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
       if (expressionPointcut == null) {
          return null;
       }
       //创建advisor实现类
       return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
             this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
    }
    private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
    //获取切面注解Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class 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()); ajexp.setBeanFactory(this.beanFactory); return ajexp; }
    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();
            this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
            this.aspectJAdviceMethod = aspectJAdviceMethod;
            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); } }
    private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
            return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
                    this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
        }
    
    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);
            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)) {
                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()) {
    //是切点的返回null
    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; }

    二、代理对象的生成

    AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor,所以在bean初始化完成后会调用postProcessAfterInitialization方法

    1、postProcessAfterInitialization()

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean != null) {
    Object cacheKey
    = this.getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return this.wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }

    2、wrapIfNecessary()

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
                return bean;
            }
            if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
                return bean;
            }
    //判断当前bean是不是基础类型的bean,或者指定类型的bean 不需要代理
    //shoulaSkip在上面也解析过一次,所以这里一般是从缓存中获取
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice.
    //获取增强器 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE);
    //创建代理 Object proxy
    = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } //放入缓存中 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }

    3.1、getAdvicesAndAdvisorsForBean()

    protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
            //查找符合条件的增强器
            List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
            if (advisors.isEmpty()) {
                return DO_NOT_PROXY;
            }
            return advisors.toArray();
        }
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
            //找到候选的增强器,shouldSkip有该方法,从换从中获取
            List<Advisor> candidateAdvisors = findCandidateAdvisors();
            //从候选的中选出能用的增强器
            List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
            extendAdvisors(eligibleAdvisors);
            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()) {
                return candidateAdvisors;
            }
            List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
            for (Advisor candidate : candidateAdvisors) {
                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) {
            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 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<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
            classes.add(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;
        }

    3.2 createProxy()

    protected Object createProxy(
                Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
            //获取容器的类型
            if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
                AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
            }
    
            ProxyFactory proxyFactory = new ProxyFactory();
            proxyFactory.copyFrom(this);
            //判断是否配置了proxyTargetClass
            if (!proxyFactory.isProxyTargetClass()) {
                if (shouldProxyTargetClass(beanClass, beanName)) {
                    proxyFactory.setProxyTargetClass(true);
                }
                else {
                    //检测 beanClass 是否实现了接口,若未实现,则将 proxyFactory 的成员变量 proxyTargetClass 设为 true
                    evaluateProxyInterfaces(beanClass, proxyFactory);
                }
            }
             //获取容器中的方法增强器
            Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
            proxyFactory.addAdvisors(advisors);
            proxyFactory.setTargetSource(targetSource);
            customizeProxyFactory(proxyFactory);
    
            proxyFactory.setFrozen(this.freezeProxy);
            if (advisorsPreFiltered()) {
                proxyFactory.setPreFiltered(true);
            }
            //创建代理对象
            return proxyFactory.getProxy(getProxyClassLoader());
        }
    public Object getProxy(ClassLoader classLoader) {
            return createAopProxy().getProxy(classLoader);
        }
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
            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.");
                }
                //是接口用jdk代理
                if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                    return new JdkDynamicAopProxy(config);
                }
                //cglib代理
                return new ObjenesisCglibAopProxy(config);
            }
            //jdk代理
            else {
                return new JdkDynamicAopProxy(config);
            }
        }
    //创建jdk代理
    public Object getProxy(ClassLoader classLoader) {
            if (logger.isDebugEnabled()) {
                logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
            }
            Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
            findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
            return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
        }

    三、代理对象方法的调用

    这里看下jdk动态代理的调用

    org.springframework.aop.framework.JdkDynamicAopProxy#invoke

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            MethodInvocation invocation;
            Object oldProxy = null;
            boolean setProxyContext = false;
    
            TargetSource targetSource = this.advised.targetSource;
            Class<?> targetClass = null;
            Object target = null;
    
            try {
                //equal()方法
                if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
                    // The target does not implement the equals(Object) method itself.
                    return equals(args[0]);
                }
                //hashcode()方法
                else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                    // The target does not implement the hashCode() method itself.
                    return hashCode();
                }
                //方法的类是不是DecoratingProxy
                else if (method.getDeclaringClass() == DecoratingProxy.class) {
                    // There is only getDecoratedClass() declared -> dispatch to proxy config.
                    return AopProxyUtils.ultimateTargetClass(this.advised);
                }
               //有没有实现Advised
                else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
                        method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                    // Service invocations on ProxyConfig with the proxy config...
                    return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
                }
    
                Object retVal;
                //是不是有配置exposeProxy,為true的放入threadLocal中,然后就可以通过AopContext.currentProxy()拿到代理对象
                if (this.advised.exposeProxy) {
                    // Make invocation available if necessary.
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }
    
                // May be null. Get as late as possible to minimize the time we "own" the target,
                // in case it comes from a pool.
                //获取被代理对象
                target = targetSource.getTarget();
                if (target != null) {
                    targetClass = target.getClass();
                }
    
                // Get the interception chain for this method.
                //把增强器转为方法拦截器链
                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    
                // Check whether we have any advice. If we don't, we can fallback on direct
                // reflective invocation of the target, and avoid creating a MethodInvocation.
                //若方法拦截器为空,则直接反射调用目标方法
                if (chain.isEmpty()) {
                    // We can skip creating a MethodInvocation: just invoke the target directly
                    // Note that the final invoker must be an InvokerInterceptor so we know it does
                    // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
                    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                    retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
                }
                else {
                    // We need to create a method invocation...
                    //创建方法拦截器调用链
                    invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                    // Proceed to the joinpoint through the interceptor chain.
                    //执行方法拦截器调用链
                    retVal = invocation.proceed();
                }
    
                // Massage return value if necessary.
                //获取方法返回值
                Class<?> returnType = method.getReturnType();
                if (retVal != null && retVal == target &&
                        returnType != Object.class && returnType.isInstance(proxy) &&
                        !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                    // Special case: it returned "this" and the return type of the method
                    // is type-compatible. Note that we can't help if the target sets
                    // a reference to itself in another returned object.
                    //如果方法返回值是this,则将代理对象赋值给retVal
                    retVal = proxy;
                }
                //如果方法返回值为基础类型并且不是void,但是返回了null,则报错
                else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
                    throw new AopInvocationException(
                            "Null return value from advice does not match primitive return type for: " + method);
                }
                return retVal;
            }
            finally {
                if (target != null && !targetSource.isStatic()) {
                    // Must have come from TargetSource.
                    targetSource.releaseTarget(target);
                }
                if (setProxyContext) {
                    // Restore old proxy.
                    AopContext.setCurrentProxy(oldProxy);
                }
            }
        }
  • 相关阅读:
    linux下启动和关闭网卡命令及DHCP上网
    python 编码问题
    paddlepaddle
    Convolutional Neural Network Architectures for Matching Natural Language Sentences
    deep learning RNN
    Learning Structured Representation for Text Classification via Reinforcement Learning 学习笔记
    Python IO密集型任务、计算密集型任务,以及多线程、多进程
    EM 算法最好的解释
    tensorflow 调参过程
    tensorflow 学习纪录(持续更新)
  • 原文地址:https://www.cnblogs.com/pjfmeng/p/13986349.html
Copyright © 2011-2022 走看看