spring Aop(3)--源码解析

 

接着上一章的问题,spring是怎么进行创建Aop代理对象的


前面AbstractAutowireCapableBeanFactory.createBean()这个方法ioc之前已经说过,下面是部分熟悉代码

try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
        return bean;
      }
    }
    catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
          "BeanPostProcessor before instantiation of bean failed", ex);
    }

    try {
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
        logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
    }

在调用 doCreateBean(beanName, mbdToUse, args);实例化bean的时候前面注意:

// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

从注释上可以看出让其有机会返回一个代理对象

我们往里走AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation

这里获取所有后置处理器,里面就有

该类继承AbstractAutoProxyCreator,然后调用AbstractAutoProxyCreator.postProcessBeforeInstantiation

AspectJAwareAdvisorAutoProxyCreator.shouldSkip

AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors

BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors

就这样我们在实例化一个bean的时候例如实例化UserA前的时候调用AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation扫描出所有advisor放入缓存中

接着在bean实例化放入beanFactory三级缓存后进入initiallizeBean,在这里将会返回一个代理对象

AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization

接着这里调用AnnotationAwareAspectJAutoProxyCreator后置处理器

getAdvicesAndAdvisorsForBean这里是获取前面我们放入缓存里的advisor,注释上可以看出如果能获取到该类的advice那么就需要创建代理对象

我们跟进去瞧瞧

到这里不就是前面调用了buildAspectJAdvisors放入缓存了吗

我们到这里将其获取出来

接着我们进入

判断能否拿到有该类切点的advisor

 调用AopUtil.canApply用来判断该类是否是切点的类,如果是那么就将Advisor放入返回

毫无疑问这里是有的,所以将其返回

 接着我们拿到之后开始创建代理对象

careteProxy里再调用CglibAopProxy.getProxy来创建一个cglib代理

public Object getProxy(@Nullable ClassLoader classLoader) {
    if (logger.isTraceEnabled()) {
      logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
    }

    try {
      Class<?> rootClass = this.advised.getTargetClass();
      Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

      Class<?> proxySuperClass = rootClass;
      if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
        proxySuperClass = rootClass.getSuperclass();
        Class<?>[] additionalInterfaces = rootClass.getInterfaces();
        for (Class<?> additionalInterface : additionalInterfaces) {
          this.advised.addInterface(additionalInterface);
        }
      }

      // Validate the class, writing log messages as necessary.
      validateClassIfNecessary(proxySuperClass, classLoader);

      // Configure CGLIB Enhancer...
      Enhancer enhancer = createEnhancer();
      if (classLoader != null) {
        enhancer.setClassLoader(classLoader);
        if (classLoader instanceof SmartClassLoader &&
            ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
          enhancer.setUseCache(false);
        }
      }
      enhancer.setSuperclass(proxySuperClass);
      enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
      enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
      enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

      Callback[] callbacks = getCallbacks(rootClass);
      Class<?>[] types = new Class<?>[callbacks.length];
      for (int x = 0; x < types.length; x++) {
        types[x] = callbacks[x].getClass();
      }
      // fixedInterceptorMap only populated at this point, after getCallbacks call above
      enhancer.setCallbackFilter(new ProxyCallbackFilter(
          this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
      enhancer.setCallbackTypes(types);

      // Generate the proxy class and create a proxy instance.
      return createProxyClassAndInstance(enhancer, callbacks);
    }

到这里我们是不是很熟悉,就跟我们前面一章提到的利用cglib动态代理生成一个代理对象

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值