美文网首页Spring相关时序图系列
Spring AOP(3)基于XML理解代理类的创建

Spring AOP(3)基于XML理解代理类的创建

作者: 涣涣虚心0215 | 来源:发表于2021-01-06 00:49 被阅读0次

    Spring IOC(9)里面介绍了三级缓存的时候,提到了AOP创建代理类的内容,有两个地方会去调用AbstractAutoProxyCreator.wrapIfNecessary()去创建代理类。
    上一篇Spring AOP(2)分析了下通过ProxyFactoryBean创建Proxy的过程,总结来说就是ProxyFactoryBean是FactoryBean,它的getObject()方法会将配置的Advice实例化,并与PointCut组合成Advisor加入到InteceptorChain中,然后实例化target实例,最后通过ProxyCreatorSupport去创建AopProxy,再通过AopProxy创建target实例的代理对象。
    那么这一章主要根据XML配置AOP,看看Spring是如何创建Proxy代理对象。

    从XML配置看起

    <bean id="student" class="com.gary.spring.Student"/>
    <bean id="adviceHandler" class="com.gary.spring.AdviceHandler"/>
    <aop:config>
        <aop:aspect id="aspect" ref="adviceHandler">
            <aop:pointcut id="pointCut" expression="execution(* com.gary.spring.Student.*(..)) "/>
            <aop:around method="doAround" pointcut-ref="pointCut"/>
        </aop:aspect>
    </aop:config>
    

    定义了一个student bean,是target。
    定义一个adviceHandler bean,用来做通知增强的。
    再通过aop定义切面,组合了pointCut和Advice。
    Spring启动的时候会读取Resource并通过BeanDefinitionReader加载BeanDefinition到BeanFactory中,跟<bean/>标签一样,对于aop:config标签,在loadBeanDefinitions的时候也有特殊的处理。

    loadBeanDefinitions
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        //判断Namespace是不是http://www.springframework.org/schema/beans
        if (delegate.isDefaultNamespace(root)) {
            NodeList nl = root.getChildNodes();
            //loop配置文件中的node
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                if (node instanceof Element) {
                    Element ele = (Element) node;
                    //如果是http://www.springframework.org/schema/beans,就parseDefaultElement
                    if (delegate.isDefaultNamespace(ele)) {
                        parseDefaultElement(ele, delegate);
                    }
                    //除了beans之外的,比如http://www.springframework.org/schema/aop,就走parseCustomElement
                    else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            delegate.parseCustomElement(root);
        }
    }
    
    • parseDefaultElement
      对于bean相关的解析
    //parseDefaultElement主要完成<import><alias><bean><beans>标签的解析
    private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
            importBeanDefinitionResource(ele);
        }
        else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
            processAliasRegistration(ele);
        }
        else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
            processBeanDefinition(ele, delegate);
        }
        else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
            // recurse
            doRegisterBeanDefinitions(ele);
        }
    }
    //<bean>标签的解析
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                //将BeanDefinition注册到BeanFactory中
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" +
                        bdHolder.getBeanName() + "'", ele, ex);
            }
            // Send registration event.
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
    }
    
    • parseCustomElement
      解析一些aop或者tx相关的配置
    public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
        String namespaceUri = getNamespaceURI(ele);
        if (namespaceUri == null) {
            return null;
        }
        //根据namespace获取到对应的NamespaceHandler,下面图中可以看到默认提供13种handler
        //aop就通过反射生成AopNamespaceHandler,并且调用init()方法
        NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
        if (handler == null) {
            error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
            return null;
        }
            //AopNamespaceHandler会
        return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
    }
    
    handlerMappings

    resolve方法完成了AopNamespaceHandler以及初始化,而AopNamespaceHandler则加载了aop:config对应的BeanDefinitionParser

    这里getHandlerMappings()在第一次调用的时候,会通过PropertiesLoaderUtils.loadAllProperties()加载"META-INF/spring.handlers"目录下配置的property(通过ClassLoader.getResource()拿到URL,再通过URLconnection打开Inputstream去读取property),会分别找到spring-aop,spring-beans等jar包下面的spring.handlers配置。

    //resolve方法会加载并创建AopNamespaceHandler对象
    public NamespaceHandler resolve(String namespaceUri) {
        Map<String, Object> handlerMappings = getHandlerMappings();
        Object handlerOrClassName = handlerMappings.get(namespaceUri);
        String className = (String) handlerOrClassName;
        try {
            //根据namespace在handlerMappings里找到对应的handler,这里通过反射加载class并且实例化
            Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
            NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
            //调用AopNamespaceHandler
            namespaceHandler.init();
            handlerMappings.put(namespaceUri, namespaceHandler);
            return namespaceHandler;
        }
        catch (ClassNotFoundException ex) {
            throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
                    "] for namespace [" + namespaceUri + "]", ex);
        }
        catch (LinkageError err) {
            throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
                    className + "] for namespace [" + namespaceUri + "]", err);
    
    }
    //AopNamespaceHandler的init方法会加载BeanDefinitionParser,aop:config对应的parser是ConfigBeanDefinitionParser
    public void init() {
        // In 2.0 XSD as well as in 2.1 XSD.
        registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
    
        // Only in 2.0 XSD: moved to context namespace as of 2.1
        registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
    }   
    

    ConfigBeanDefinitionParser是核心,主要注册了org.springframework.aop.config.internalAutoProxyCreator这个BeanDefinition,实例是AspectJAwareAdvisorAutoProxyCreator,这个类继承了AbstractAutoProxyCreator,是一个BeanPostProcessor。至此,跟AOP创建Proxy有关系的类的BeanDefinition注册到了BeanFactory。
    代码如下:

    public BeanDefinition parse(Element element, ParserContext parserContext) {
        CompositeComponentDefinition compositeDef =
                new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
        parserContext.pushContainingComponent(compositeDef);
        //这个是核心,创建auto proxy creator
        configureAutoProxyCreator(parserContext, element);
    
        List<Element> childElts = DomUtils.getChildElements(element);
        for (Element elt: childElts) {
            String localName = parserContext.getDelegate().getLocalName(elt);
            //解析PointCut
            if (POINTCUT.equals(localName)) {
                parsePointcut(elt, parserContext);
            }
            //解析Advisor
            else if (ADVISOR.equals(localName)) {
                parseAdvisor(elt, parserContext);
            }
            //解析Aspect
            //该示例里会将pointcut(AspectJExpressionPointcut)注册BeanDefinition,
            //以及根据aop:around注册advice(AspectJAroundAdvice)的BeanDefinition
            //还有AspectJPointcutAdvisor的BeanDefinition(内部很多innerBean需要实例化)
            else if (ASPECT.equals(localName)) {
                parseAspect(elt, parserContext);
            }
        }
    
        parserContext.popAndRegisterContainingComponent();
        return null;
    }
    //创建auto proxy creator
    private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
        AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
    }
    public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(
            BeanDefinitionRegistry registry, @Nullable Object source) {
        //这边能够看到需要AspectJAwareAdvisorAutoProxyCreator
        return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);
    }
    private static BeanDefinition registerOrEscalateApcAsRequired(
            Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    
        //核心:org.springframework.aop.config.internalAutoProxyCreator的注册
        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;
        }
    
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        //这边就是注册了BeanDefinition,名字就是org.springframework.aop.config.internalAutoProxyCreator,
        //实例是AspectJAwareAdvisorAutoProxyCreator
        registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
        return beanDefinition;
    }
    

    可以看到上述Spring加载完配置文件之后,BeanFactory里面有这五个BeanDefinition。
    如果配置文件使用的是<aop:advisor>那么就是DefaultBeanFactoryPointcutAdvisor,而不是AspectJPointcutAdvisor

    BeanDefinitions

    注册BeanPostProcessor

    如果不用ApplicationContext,而是使用DefaultListableBeanFactory的时候,需要添加BeanPostProcessor,
    而这个BeanPostProcessor就是上面添加的org.springframework.aop.config.internalAutoProxyCreator,实现类是AspectJAwareAdvisorAutoProxyCreator

    Resource resource = new ClassPathResource("applicationContext.xml");
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    BeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    beanDefinitionReader.loadBeanDefinitions(resource);
    //获取BeanPostProcessor相关的Bean Name。
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    //添加BeanPostProcessor
    BeanPostProcessor pp = beanFactory.getBean(postProcessorNames[0], BeanPostProcessor.class);
    beanFactory.addBeanPostProcessor(pp);
    Student student = (Student) beanFactory.getBean("student");
    student.sayName();
    

    至此,AOP创建Proxy所需要的BeanDefinition以及BeanPostProcessor都准备完毕。

    getBean()创建Proxy对象

    在正式创建对象的时候,整体逻辑都是类似的,不同的是在createBean()内部,doCreateBean()之前会调用BeanPostProcessor的postProcessBeforeInstantiation()

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
    
        。。。省略代码
    
        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            // 调用BeanPostProcessors,即AspectJAwareAdvisorAutoProxyCreator
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        。。。
    
        try {
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        。。。
    }
    

    具体的resolveBeforeInstantiation(): 主要是实例化Advisor以及相关的bean(AspectJExpressionPointcut,AspectJAroundAdvice),并将对应的beanClass放入advisedBeans缓存中。

    //遍历所有的BeanPostProcessors,调用postProcessBeforeInstantiation,即实例化之前的准备
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            //找到InstantiationAwareBeanPostProcessor的实现类
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }
    //AspectJAwareAdvisorAutoProxyCreator的postProcessBeforeInstantiation方法是在父类AbstractAutoProxyCreator中实现的
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        Object cacheKey = getCacheKey(beanClass, beanName);
        //这里进行去重,避免重复
        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            //主要代码是这里,isInfrastructureClass判断beanClass是不是Advice,Point,Advisor
            //     如果是,就直接加入advisedBeans缓存,如果不是就走shouldSkip()。
            //shouldSkip()里面主要调用findCandidateAdvisors()
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }
    
        // Create proxy here if we have a custom TargetSource.
        // Suppresses unnecessary default instantiation of the target bean:
        // The TargetSource will handle target instances in a custom fashion.
        //这边如果设置了TargetSource,就直接在这里创建Proxy
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
    
        return null;
    }
    //检查是不是AOP相关的bean,Advice或者PointCut或者Advisor
    protected boolean isInfrastructureClass(Class<?> beanClass) {
        boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
                Pointcut.class.isAssignableFrom(beanClass) ||
                Advisor.class.isAssignableFrom(beanClass) ||
                AopInfrastructureBean.class.isAssignableFrom(beanClass);
        if (retVal && logger.isTraceEnabled()) {
            logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
        }
        return retVal;
    }
    //核心逻辑,调用findCandidateAdvisors查找关联的Advisor,在过程中会对AOP用到的bean进行实例化
    protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        // TODO: Consider optimization by caching the list of the aspect names
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        for (Advisor advisor : candidateAdvisors) {
            if (advisor instanceof AspectJPointcutAdvisor &&
                    ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
                return true;
            }
        }
        return super.shouldSkip(beanClass, beanName);
    }
    //advisorRetrievalHelper内部持有BeanFactory的引用,通过advisorRetrievalHelper进行查找Advisor bean
    protected List<Advisor> findCandidateAdvisors() {
        Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
        return this.advisorRetrievalHelper.findAdvisorBeans();
    }
    //查找Advisor
    public List<Advisor> findAdvisorBeans() {
        // Determine list of advisor bean names, if not cached already.
        String[] advisorNames = this.cachedAdvisorBeanNames;
        if (advisorNames == null) {
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the auto-proxy creator apply to them!
            //这里能够找到Advisor,也就是上面loadBeanDefinition里面提到的AspectJPointcutAdvisor beanName
            advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                    this.beanFactory, Advisor.class, true, false);
            this.cachedAdvisorBeanNames = advisorNames;
        }
        if (advisorNames.length == 0) {
            return new ArrayList<>();
        }
    
        List<Advisor> advisors = new ArrayList<>();
        //这边拿到Advisor的bean name
        for (String name : advisorNames) {
            if (isEligibleBean(name)) {
                //检查bean是不是正在创建
                if (this.beanFactory.isCurrentlyInCreation(name)) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Skipping currently created advisor '" + name + "'");
                    }
                }
                else {
                    try {
                        //调用BeanFactory.getBean()实例化Advisor
                        advisors.add(this.beanFactory.getBean(name, Advisor.class));
                    }
                    。。。
                }
            }
        }
        return advisors;
    }
    

    上述代表看出这里postProcessBeforeInstantiation()方法,主要是对Advisor实例化,一般来说没有设置target source的话,是不会有返回值的。
    那么getBean()正常走到doCreateBean()-->initializeBean()开始初始化Bean的时候,会在调用初始化方法前后分别调用BeanPostProcessor的postProcessBeforeInitialization()和postProcessAfterInitialization()。
    那么对于AspectJAwareAdvisorAutoProxyCreator,由父类AbstractAutoProxyCreator提供这两个方法。

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        。。。
    
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            //调用BeanPostProcessor的postProcessBeforeInitialization
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
    
        try {
            //调用初始化方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            //调用BeanPostProcessor的postProcessAfterInitialization
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
    
        return wrappedBean;
    }
    //AbstractAutoProxyCreator在初始化前的postProcessBeforeInitialization没有任何逻辑
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }
    //核心代码在这,通过wrapIfNecessary()创建对象的代理类
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                 //核心代码,创建代理
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
    

    WrapIfNecessary:第一步就是根据Advisor去验证是不是有符合的Advisor,如果有,就表示可以创建代理类。

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //为了避免重复调用,targetSource存在的,在postProcessBeforeInstantiation()就已经提前创建了Proxy
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        //如果是Advisor相关的bean,也不需要创建Proxy
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        //这里跟postProcessBeforeInstantiation()的方法一样,再次过滤一下Advisor相关的bean
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
        //下面就是非Advisor相关的bean,创建Proxy
        // Create proxy if we have advice.
        //找到合适的Advisor
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        //如果specificInterceptors不为空,则创建Proxy
        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;
    }
    //找到合适的Advisor
    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();
    }
    //查找合适的Advisor
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        //这个在前面分析过,会找到所有的Advisor,并且实例化
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        //这里就是检查这些Advisor是不是能够apply
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        //这里会添加一个ExposeInvocationInterceptor.ADVISOR
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }
    //检查Advisor是否能被apply
    public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        }
        List<Advisor> eligibleAdvisors = new ArrayList<>();
        for (Advisor candidate : candidateAdvisors) {
            //如果Advisor是IntroductionAdvisor,同时调用canApply()检查
            if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                eligibleAdvisors.add(candidate);
            }
        }
        //是否hasIntroduction
        boolean hasIntroductions = !eligibleAdvisors.isEmpty();
        for (Advisor candidate : candidateAdvisors) {
            if (candidate instanceof IntroductionAdvisor) {
                // already processed
                continue;
            }
            //同样调用canApply
            if (canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }
        return eligibleAdvisors;
    }
    //检查canApply
    public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
        //如果是IntroductionAdvisor,就用IntroductionAdvisor方式验证
        if (advisor instanceof IntroductionAdvisor) {
            return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
        }
        //如果是PointCutAdvisor,就拿到pointCut再对targetClass进行验证
        //我们这里是AspectJPointcutAdvisor,所以走这边
        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;
        }
    }
    //因为是AspectJPointcutAdvisor,所以需要PointCut来验证
    public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
        Assert.notNull(pc, "Pointcut must not be null");
        //通过pointCut的classFilter来验证
        if (!pc.getClassFilter().matches(targetClass)) {
            return false;
        }
        //拿到PointCut的methodMatch而
        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<>();
        //检查是否是ProxyClass
        if (!Proxy.isProxyClass(targetClass)) {
            classes.add(ClassUtils.getUserClass(targetClass));
        }
        classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
    
        for (Class<?> clazz : classes) {
            //通过反射拿到所有method
            Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
            for (Method method : methods) {
                //通过introductionAwareMethodMatcher判断method是不是符合PointCut的约定
                //如果有一个符合,就返回true,表示需要该Advisor适用,可以创建代理类
                if (introductionAwareMethodMatcher != null ?
                        introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                        methodMatcher.matches(method, targetClass)) {
                    return true;
                }
            }
        }
    
        return false;
    }
    

    这里需要注意的是查找canApply的Advisor之后,会调用extendAdvisors,添加一个ExposeInvocationInterceptor.ADVISOR,这个在调用invoke proxy的时候再详解。

    最后创建Proxy: 这里主要就是将上面找到的findEligibleAdvisors()可以用的Advisor,将他们封装好添加到AdvisedSupport中,在Proxy被invoke的时候,会用到这些Advisors。

    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
            @Nullable Object[] specificInterceptors, TargetSource targetSource) {
    
        //如果是ConfigurableListableBeanFactory,就给beanName对应的BeanDefinition设置一个originalTargetClass,指向原对象beanClass
        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }
        //使用proxyFactory来创建代理类
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);
    
        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                //设置proxyTargetClass为true
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                //为proxyFactory.addInterface设置接口
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
        //设置Advisor,主要是将Advice或者MethodInteceptor转换成Advisor
        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());
    }
    
    protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
        // Handle prototypes correctly...
        Advisor[] commonInterceptors = resolveInterceptorNames();
        List<Object> allInterceptors = new ArrayList<>();
        if (specificInterceptors != null) {
            allInterceptors.addAll(Arrays.asList(specificInterceptors));
            if (commonInterceptors.length > 0) {
                if (this.applyCommonInterceptorsFirst) {
                    allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
                }
                else {
                    allInterceptors.addAll(Arrays.asList(commonInterceptors));
                }
            }
        }
        
        Advisor[] advisors = new Advisor[allInterceptors.size()];
        for (int i = 0; i < allInterceptors.size(); i++) {
             //对Advice和MethodInteceptor进行封装成Advisor
            advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
        }
        return advisors;
    }
    //主要对Advice和MethodInteceptor进行封装成Advisor
    public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
        //如果是Advisor,直接返回
        if (adviceObject instanceof Advisor) {
            return (Advisor) adviceObject;
        }
        //如果不是Advice,就报错
        if (!(adviceObject instanceof Advice)) {
            throw new UnknownAdviceTypeException(adviceObject);
        }
        Advice advice = (Advice) adviceObject;
        //如果是MethodInteceptor,直接包装
        if (advice instanceof MethodInterceptor) {
            // So well-known it doesn't even need an adapter.
            return new DefaultPointcutAdvisor(advice);
        }
        //Advice就需要调用AdvisorAdapter.supportAdvice()检查是不是适合
        for (AdvisorAdapter adapter : this.adapters) {
            // Check that it is supported.
            if (adapter.supportsAdvice(advice)) {
                return new DefaultPointcutAdvisor(advice);
            }
        }
        throw new UnknownAdviceTypeException(advice);
    }
    

    补充:proxyTargetClass的设置对proxy的创建有影响:

    proxyTargetClass 目标对象特征 代理效果
    true 目标对象实现了接口 使用CGLIB代理机制
    true 目标对象没有接口(只有实现类) 使用CGLIB代理机制
    false 目标对象实现了接口 使用JDK动态代理机制(代理所有实现了的接口)
    false 目标对象没有接口(只有实现类) 使用CGLIB代理机制

    相关文章

      网友评论

        本文标题:Spring AOP(3)基于XML理解代理类的创建

        本文链接:https://www.haomeiwen.com/subject/woaboktx.html