Spring Aop动态代理实现-1(参照源码)

注:本文参考《Spring源码深度解析》,结合代码实际讲述AOP过程实现。具体步骤请参考目录分层,可以让阅读更清晰,因为Spring代码封装比较强,需分层级方能更好理解
Spring AOP的具体实现可以查看下面这个图
在这里插入图片描述

1.注册切面处理器

AOP的处理器注册在AopNamespaceHandler这个类中,我们直接进来查看

public class AopNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {
        /**
         * 注册一个切面处理器
         * registerBeanDefinitionParser其实就是构造一个对应的key-value的结构
         */
        registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        //------其他的注册信息,不管
    }
}

2.1 BeanDefinitionParser的parse操作

因为AspectJAutoProxyBeanDefinitionParser是继承自BeanDefinitionParser,所以需要实现的是她的parse方法,我们来看这边的具体操作.往下去分析每一个函数的具体操作

    /**
     * 这个接口是实现了BeanDefinitionParser接口,所以他的入口在这边
     */
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        /**
         * 注册 AnnotationAwareAspectJAutoProxyCreator,这个是我们的关键类
         */
        AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
        /**
         * 对注解中子类的处理
         */
        extendBeanDefinition(element, parserContext);
        return null;
    }

3.1 注册构造器

主要看第一个注册的方法.

    public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
        /**
         * 这边会去注册一个AnnotationAwareAspectJAutoProxyCreator类,这个类应该是主要做AOP的@Point注解解析的
         */
        BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(),
            parserContext.extractSource(sourceElement));
        /**
         * proxy-target-class属性和expose proxy属性的处理
         */
        useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
        /**
         * 注册组件
         */
        registerComponentIfNecessary(beanDefinition, parserContext);
    }
4.1 注册 AnnotationAwareAspectJAutoProxyCreator
    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
        /**
         * 这边可以看到他是传入一个AnnotationAwareAspectJAutoProxyCreator的class对象
         */
        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }
5.1 存在两个构造器的处理

存在两个构造器,这边会根据优先级去拿到高的构造器

    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        /**
         * 如果已经存在对应的自动代理创造器,并且两个不一致,根据优先级Priority来判断使用哪个
         */
        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;
        }
     //---------------------略
    }
5.2 不存在构造器

如果不存在构造器则会去创建一个并注册,其实就是放入容器的操作

    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        //---------------------略
        /**
         * 不存在该创造器,则会去注册一个
         */
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        /**
         * 这边就是具体的注册,应该是BeanDefinitionRegister的具体实现类往容器添加这个创造器吧
         */
        registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
        return beanDefinition;
    }
4.2 proxy-target-class属性和expose proxy属性处理

这边就是实现两个属性获取和设值的操作

    private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
        if (sourceElement != null) {
            boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
            if (proxyTargetClass) {
                /**
                 * 10.proxy-target-class属性的处理--强制使用CGLIB代理(true).
                 */
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
            if (exposeProxy) {
                /**
                 * 11.expose-proxy属性的处理
                 */
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }
    public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
        /**
         * 13.对属性的一个设置
         */
        if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
            BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
            definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
        }
    }

    public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
        if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
            BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
            definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
        }
    }
4.3 注册组件

往容器中添加组件

    private static void registerComponentIfNecessary(BeanDefinition beanDefinition, ParserContext parserContext) {
        if (beanDefinition != null) {
            BeanComponentDefinition componentDefinition =
                new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
            parserContext.registerComponent(componentDefinition);
        }
    }

3.2 其他构造器的处理

这边的操作是往每一个节点去添加对应的BeanDefinition.我们主要还是关注在上面的操作

private void extendBeanDefinition(Element element, ParserContext parserContext) {
        /**
         * 15.添加子节点的对应BeanDefinition
         */
        BeanDefinition beanDef = parserContext.getRegistry().getBeanDefinition(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
        if (element.hasChildNodes()) {
            addIncludePatterns(element, parserContext, beanDef);
        }
    }

到这边位置,我们的构造器已经添加到容器中,下面就是看他具体是怎么处理的.

2.切面构造器AnnotationAwareAspectJAutoProxyCreator的处理

我们来看一下构造器的继承关系,一直往上,他其实是实现了BeanPostProcessor这个接口,实现该接口就回去实现他的postProcessAfterInitialization方法,这也是我们需要重点关注的地方.
在这里插入图片描述

3.1关于BeanPostProcessor

关于BeanPostProcessor这个接口其实是做了Bean调用的增强,在网上找了一个图,大概表示这个增强过程
在这里插入图片描述

3.2 postProcessAfterInitialization的处理

postProcessAfterInitialization这个方法的实现,我们要追索到继承下来的AbstractAutoProxyCreator这个类.

4.1 缓存查找存在key

如果能找到key对应的Object则直接返回

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean != null) {
            /**
             * 只是一个简单的key构造的操作,key为:beanClassName_beanName
             */
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                //..............略
            }
        }
        return bean;
    }

4.2 缓存查找不存在key

找不到对应的object,则进入包装方法

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                /**
                 * 如果这个key不存在,则封装成对应的对象返回
                 */
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
5.1 不需要处理的情况

这边描述了四种不需要处理的情况

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        /**
         * 不需要代理的情况:1.已经处理过了2.无需增强3.基础设施类4.已配置了bean
         */
        if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
        //..................略
 }
5.2 获取Advisor增强方法数组
 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //...............略
        /**
         * 获取增强方法
         * @see org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
         */
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(),beanName, null);
		//...............略        
}

直接查看AbstractAdvisorAutoProxyCreator类对#getAdvicesAndAdvisorsForBean的实现

    @Override
    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();
    }
6.1 查找所有Advisors
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        /**
         * @see AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()
         */
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        //............略
    }

直接查看AnnotationAwareAspectJAutoProxyCreator对这个方法的重写
这边保留了父类对xml配置的切面查找的操作,并引入注解式配置的查找

    @Override
    protected List<Advisor> findCandidateAdvisors() {
        /**
         * 这边依然会去调用父类的xml方式查找advisor的操作
          */
        List<Advisor> advisors = super.findCandidateAdvisors();
        /**
         * 这边查找注解式的advisor增强方法,然后添加数组
         */
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        return advisors;
    }
7.1查找所有切面注解方法

因为csdn目录只能支持到六级,所以往下对AspectJ注解处理的部分需要往另一个文章中查看: 查找所有切面注解方法

6.2 查找适合的Advisors
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		//.....略
        /**
         * 找到合适的增强器
         */
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        extendAdvisors(eligibleAdvisors);
        /**
         * 排序和返回
         */
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }
7.1 引界增强和普通Bean增强的处理
    protected List<Advisor> findAdvisorsThatCanApply(
        List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
            //过滤得到对应的Advisor
            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) {
            //略过引介增强,处理普通bean的增强
            if (candidate instanceof IntroductionAdvisor) {
                // already processed
                continue;
            }
            //canApply根据规则判断是否可以作为增强类,不细究了
            if (canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }
        return eligibleAdvisors;
    }
6.3 排序返回
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
       //..................略
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }
5.3 创建Proxy
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
       //.............略
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            //拿到所有的advisors之后要进行代理的创建了
            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;
    }
6.1 代理创建和代理实现

直接查看另一篇博客:代理创建和代理实现

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

了-凡

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值