Spring AOP源码剖析

Spring AOP源码剖析,第1张

1.AOP基础用例准备

Bean定义

@Component
public class AopBean {

   public void tech(){
      System.out.println("java spring aop learning......");
   }
}

Aspect定义

@Component
@Aspect
public class AopAspect {
   @Pointcut("execution(* com.lagou.edu.AopBean.tech(..))")
   public void pointcut(){
   }
   @Before("pointcut()")
   public void before() {
      System.out.println("before method ......");
   }
}

SpringConfig定义

@Configuration
@ComponentScan(basePackages = {"com.lagou.edu"})
@EnableAspectJAutoProxy
public class SpringConfig {
}

测试用例

/**
 * 测试⽤例: Aop 代理对象创建
 */
@Test
public void testAopProxyBuild(){
   ApplicationContext applicationContext = new
         AnnotationConfigApplicationContext(SpringConfig.class);
   AopBean aopBean = applicationContext.getBean(AopBean.class);
   aopBean.tech();
}
2. 时机点分析


我们发现在 getBean 之前, AopBean对象已经产⽣(即在第⼀⾏初始化代码中完成),⽽且该对象是⼀个代理对象(Cglib代理对象),我们断定,容器初始化过程中⽬标Ban已经完成了代理,返回了代理对象。

3. 代理对象创建流程

经过前面的学习可以看出,在容器初始化后,AopBean已经示例化了,并且是一个代理对象,那么可以看出AopBean就是在org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization方法进行实例化完成的,调用链路可追踪到
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean,

/**
* 初始化Bean
* 包括Bean后置处理器初始化
* Bean的⼀些初始化⽅法的执⾏init-methodAbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
* Bean的实现的声明周期相关接⼝的属性注⼊
*/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
   //执行所有的AwareMethods
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      // 执⾏所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器⽅法
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      // 这⾥就开始执⾏afterPropertiesSet(实现了InitializingBean接⼝)⽅法和initMethod
      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()) {
      // 整个Bean初始化完成,执⾏后置处理器⽅法
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   //循环执行后置处理器
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      Object current = processor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}


创建代理对象的后置处理器AbstractAutoProxyCreator#postProcessAfterInitialization

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      //检查下该类是否已经暴露过,可能已经创建了,⽐如A依赖B时,创建A时候,就会先去创建B
      // 当真正需要创建B时,就没必要再代理⼀次已经代理过的对象) ,避免重复创建
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

AbstractAutoProxyCreator#wrapIfNecessary

/**
 * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
 * @param bean the raw bean instance
 * @param beanName the name of the bean
 * @param cacheKey the cache key for metadata access
 * @return a proxy wrapping the bean, or the raw bean instance as-is
 */
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   // targetSourcedBeans包含,说明前⾯创建过
   if (StringUtils.hasLength(beanName) && 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;
   }

   // Create proxy if we have advice.
   // 得到所有候选Advisor,对Advisors和bean的⽅法双层遍历匹配,最终得到⼀个List,即specificInterceptors
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   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;
}

重点来了,开始创建代理对象了,进入AbstractAutoProxyCreator#createProxy方法:

/**
 * 为指定 bean 创建代理对象
 */
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
      @Nullable Object[] specificInterceptors, TargetSource targetSource) {

   if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
   }
   // 创建代理的工作交给ProxyFactory
   ProxyFactory proxyFactory = new ProxyFactory();
   proxyFactory.copyFrom(this);
   // 根据⼀些情况判断是否要设置proxyTargetClass=true
   if (!proxyFactory.isProxyTargetClass()) {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }
   // 把指定和通⽤拦截对象合并, 并都适配成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());
}

进入ProxyFactory#getProxy方法:

public Object getProxy(@Nullable ClassLoader classLoader) {
   // ⽤ProxyFactory创建AopProxy, 然后⽤AopProxy创建Proxy, 所以这⾥重要的是看获取的AopProxy对象是什么,
   // 然后进去看怎么创建动态代理, 提供了两种: jdk proxy, cglib
   return createAopProxy().getProxy(classLoader);
}

创建AOP代理工厂类ProxyCreatorSupport#createAopProxy,

protected final synchronized AopProxy createAopProxy() {
   if (!this.active) {
      activate();
   }
   // 先获取创建AopProxy的⼯⼚, 再由此创建AopProxy
return getAopProxyFactory().createAopProxy(this);
}

流程就是⽤AopProxyFactory创建AopProxy, 再⽤AopProxy创建代理对象,这⾥的AopProxyFactory默认是DefaultAopProxyFactory,看他的createAopProxy⽅法:
DefaultAopProxyFactory#createAopProxy

@Override
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() || Proxy.isProxyClass(targetClass)) {
         return new JdkDynamicAopProxy(config);
      }
      // cglib代理
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      // jdk动态代理
      return new JdkDynamicAopProxy(config);
   }
}

这里选择cglib代理还是jdk动态代理,在默认情况下会根据代理类是否实现接口来选择,如果代理对象实现了接口,那么选择jdk动态代理,如果没有实现接口,那么使用cglib代理,在强制使用cglib代理的时候就是使用cglib代理。这里AopBean没有实现接口,那么默认使用的就是cglib代理,进入CglibAopProxy#getProxy(java.lang.ClassLoader)方法,

@Override
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 (ClassUtils.isCglibProxyClass(rootClass)) {
         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...
      // 配置 Cglib 增强
      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 ClassLoaderAwareUndeclaredThrowableStrategy(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);
   }
   catch (CodeGenerationException | IllegalArgumentException ex) {
      throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
            ": Common causes of this problem include using a final class or a non-visible class",
            ex);
   }
   catch (Throwable ex) {
      // TargetSource.getTarget() failed
      throw new AopConfigException("Unexpected AOP exception", ex);
   }
}
4. 时序分析

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/884018.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-14
下一篇 2022-05-14

发表评论

登录后才能评论

评论列表(0条)

保存