AOP源码解析(四)寻找匹配的增强器


前面的函数中已经完成了所有增强器的解析,但是对于所有增强器来讲,并不一定都适用于当前的Bean,还要挑取除适合的增强器,也就是满足我们配置的通配符的增强器。具体的实现在findAdvisorsThatCanApply中。
    public static List findAdvisorsThatCanApply(List candidateAdvisors, Class clazz)
    {
        if(candidateAdvisors.isEmpty())
            return candidateAdvisors;
        List eligibleAdvisors = new LinkedList();
        //首先处理引介增强
        for(Advisor candidate:candidateAdvisors)
       if((candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz))
                eligibleAdvisors.add(candidate);
        boolean hasIntroductions = !eligibleAdvisors.isEmpty();
        for(Advisor candidate : candidateAdvisors){
            //对于普通bean的处理
            if(!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions))
                eligibleAdvisors.add(candidate);
        return eligibleAdvisors;
    }

findAdvisorsThatCanApply函数的主要功能是寻找所有增强器中适用于当前class的增强器。对于真是的匹配在canApply中实现。


    public static boolean canApply(Advisor advisor, Class targetClass, boolean hasIntroductions)
    {
        if(advisor instanceof IntroductionAdvisor)
            return ((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass);
        if(advisor instanceof PointcutAdvisor)
        {
            PointcutAdvisor pca = (PointcutAdvisor)advisor;
            return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        } else
        {
             //It dosen't have a pointcut so we assume it applies.
             return true;
        }
    }
hodMatcher introductionAwareMethodMatcher = null;
        if(methodMatcher instanceof IntroductionAwareMethodMatcher)
            introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher;
        Set classes = new HashSet(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
        classes.add(targetClass);
        for(Iterator i$ = classes.iterator(); i$.hasNext();)
        {
            Class clazz = (Class)i$.next();
            Method methods[] = clazz.getMethods();
            Method arr$[] = methods;
            int len$ = arr$.length;
            int i$ = 0;
            while(i$ < len$) 
            {
                Method method = arr$[i$];
                if(introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) || methodMatcher.matches(method, targetClass))
                    return true;
                i$++;
            }
        }

        return false;
    }

3,创建代理


在获取了所有对应bean的增强后,便可以进行代理的创建了。

protected Object createProxy(Class beanClass, String beanName, Object specificInterceptors[], TargetSource targetSource)
    {
        ProxyFactory proxyFactory = new ProxyFactory();
        //获取当前类中相关属性
        proxyFactory.copyFrom(this);
        //检查proxyTargeClass设置以及preserveTargetClass属性
        <pre name="code" class="java">        //决定对于给定的bean是否应该使用targetClass而不是他的接口代理

if(!shouldProxyTargetClass(beanClass, beanName)) { //Must allow forintroductions;cant just set interfaces to the targets interfaces only.
Class targetInterfaces[] = ClassUtils.getAllInterfacesForClass(beanClass, proxyClassLoader); for(Class<?> targetInterface : targetInterfaces) { //添加代理接口 proxyFactory.addInterface(targetInterface); } } Advisor advisors[] = buildAdvisors(beanName, specificInterceptors); for(Advisor advisor : advisors) { //加入增强器 proxyFactory.addAdvisor(advisor); } //设置要代理的类 proxyFactory.setTargetSource(targetSource); //定制代理
customizeProxyFactory(proxyFactory); //缺省值为false即izai代理被配置之后,不允许修改代理的配置。
proxyFactory.setFrozen(freezeProxy); if(advisorsPreFiltered()) proxyFactory.setPreFiltered(true); return proxyFactory.getProxy(proxyClassLoader); }

 其中,封装Advisor并加入到ProxyFactory中以及创建代理是两个相对繁琐的过程,可以通过ProxyFactory提供的addAdvisor方法直接将增强器置入代理创建工厂中,但是将拦截器封装为增强器还是需要一定的逻辑的。 

    protected Advisor[] buildAdvisors(String beanName, Object specificInterceptors[])
    {
        //解析注册的所有interceptorName
        Advisor commonInterceptors[] = resolveInterceptorNames();
        List allInterceptors = new ArrayList();
        if(specificInterceptors != null)
        {
            //加入拦截器
            allInterceptors.addAll(Arrays.asList(specificInterceptors));
            if(commonInterceptors != null)
                if(applyCommonInterceptorsFirst)
                    allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
                else
                    allInterceptors.addAll(Arrays.asList(commonInterceptors));
        }
        if(logger.isDebugEnabled())
        {
            int nrOfCommonInterceptors = commonInterceptors == null ? 0 : commonInterceptors.length;
            int nrOfSpecificInterceptors = specificInterceptors == null ? 0 : specificInterceptors.length;
            logger.debug((new StringBuilder()).append("Creating implicit proxy for bean '").append(beanName).append("' with ").append(nrOfCommonInterceptors).append(" common interceptors and ").append(nrOfSpecificInterceptors).append(" specific interceptors").toString());
        }
        Advisor advisors[] = new Advisor[allInterceptors.size()];
        for(int i = 0; i < allInterceptors.size(); i++)
             //拦截器进行封装转化为Advisor
             advisors[i] = advisorAdapterRegistry.wrap(allInterceptors.get(i));

        return advisors;
    }
    public Advisor wrap(Object adviceObject)
        throws UnknownAdviceTypeException
    {
        //如果要封装的对象本身就是Advisor类型的那么无需坐过多处理
        if(adviceObject instanceof Advisor)
            return (Advisor)adviceObject;
        //因为此封装只对Advisor和Advice两种类型的数据有效,如果不是将不能封装
        if(!(adviceObject instanceof Advice))
            throw new UnknownAdviceTypeException(adviceObject);
        Advice advice = (Advice)adviceObject;
        if(advice instanceof MethodInterceptor)
            //如果是MethodInterceptor类型则使用DefaultPointcutrAdvisor封装
            return new DefaultPointcutAdvisor(advice);
        //如果存在Advisor类型的适配器那么也同样需要进行封装
        for(Iterator i$ = adapters.iterator(); i$.hasNext();)
        {
            AdvisorAdapter adapter = (AdvisorAdapter)i$.next();
            if(adapter.supportsAdvice(advice))
                return new DefaultPointcutAdvisor(advice);
        }

        throw new UnknownAdviceTypeException(advice);
    }
由于Spring中涉及过多的拦截器,增强器,增强方法等方式来对逻辑进行增强,所以非常有必要统一封装成Advisor来进行代理的创建,完成了增强的封装过程,那么解析最终的一部就是代理的创建驭获取了。
    public Object getProxy(ClassLoader classLoader)
    {
        return createAopProxy().getProxy(classLoader);
    }

1创建代理

    protected final synchronized AopProxy createAopProxy()
    {
        if(!active)
            activate();
        //创建代理
        return getAopProxyFactory().createAopProxy(this);
    }

<pre name="code" class="java">    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.");
            if(targetClass.isInterface())
                return new JdkDynamicAopProxy(config);
            else
                return CglibProxyFactory.createCglibProxy(config);
        } else
        {
            return new JdkDynamicAopProxy(config);
        }
    }

 

到此已经完成了代理的创建,不管我们之前是否有阅读过Spring的源码,但是都或多或少地听过对于Spirng的代理中JDKProxy的实现和CglibProxy的实现。Spring是如何选取的呢?网上的介绍到处都是,现在我们就从源代码的角度分析,看看到底Spring是如何选择代理方式的。


从if中的判断条件可以看到3个方面影响着Spring的判断

  • optimize:用来控制通过CGLIB创建的代理是否使用激进的优化策略。除非完全了解AOP代理是如何优化,否则不推荐用户使用这个设置,目前这个属性仅用于CGLIB代理,对于JDK动态代理(缺省代理)无效。
  • proxyTargetClass:这个属性为treu时,目标类本身被代理而不是目标类的接口。如果这个属性值被设为true,CGLIB代理将被创建,。
  • hasNOUser Supplied Proxy Interfaces:是否存在代理接口。、
至此就是创建代理的过程,后面我们会一起分析两种动态代理的方式,以及底层的分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值