aop源码解析二:postProcessBeforeInstantiation

我们就不再从bean的加载过程开始看了 在aop源码解析一:注册BPP中 介绍到了一个后置处理器 AnnotationAwareAspectJAutoProxyCreator 我们就从这个类入手aop
先看postProcessBeforeInstantiation 很显然 是bean实例化前调用的 里面好像是处理了一些事情

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        Object cacheKey = getCacheKey(beanClass, beanName);

        if (beanName == null || !this.targetSourcedBeans.containsKey(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            //这里需要注意的是 shouldSkip方法被子类覆盖了 这个很容易忽略
            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.
        if (beanName != null) {
            //todo 这里返回null!!!
            TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
            if (targetSource != null) {
                this.targetSourcedBeans.put(beanName, Boolean.TRUE);
                Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
                Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
        }

        return null;
    }

这里shouldSkip(beanClass, beanName)方法是一个很容易忽略的方法 可能是方法名字的原因或者复杂的继承关系吧 但在这个方法的实现过程中 已经把所有的切面加载完成了
AspectJAwareAdvisorAutoProxyCreator##shouldSkip

    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) {
                if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
                    return true;
                }
            }
        }
        return super.shouldSkip(beanClass, beanName);
    }

首先找出所有的advisor 如果要加载的这个bean是一个advisor的话 当然就不会代理了
AnnotationAwareAspectJAutoProxyCreator##findCandidateAdvisors()

    protected List<Advisor> findCandidateAdvisors() {
        // Add all the Spring advisors found according to superclass rules.
        // 寻找bean的类型为Aspect.class的 我们更关心注解的形式 这里不过多的讲解
        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 = null;

        synchronized (this) {
            aspectNames = this.aspectBeanNames;
            if (aspectNames == null) {
                List<Advisor> advisors = new LinkedList<Advisor>();
                aspectNames = new LinkedList<String>();
                // 根据类型取出beanFactory中所有的bean 包括父容器 然后循环判断
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值