基本概念

概念

      1.Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。

添加注解的类:
@Aspect
@Component
public class AopDemoServices

2.Joint point(连接点):(要拦截哪个个方法的表达式)表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
如:"execution(* com.ddd.spring.source.spring.aop.source.aop.CalcServiceImpl.before(..))"

3.Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
如:@Pointcut("execution(* com.ddd.spring.source.spring.aop.source.aop.CalcServiceImpl.before(..))")

4.Advice(增强):(也可以称为通知)Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
如:@Before(value = "pointCut()")
public void before(JoinPoint joinPoint)

5.Target(目标对象):织入 Advice 的目标对象.。

6.Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程(就是界面中的通知和目标对象的连接和执行称为织入)

 

通知(Advice)类型:

(1)前置通知(Before advice):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。

(2)返回后通知(After returning advice):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。

(3)抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知。

(4)后通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。

(5)环绕通知(Around Advice):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。 环绕通知是最常用的一种通知类型。


概要图

Spring AOP 源码学习

类图

Spring AOP 源码学习

Spring AOP 原理 

Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。

如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

选择代理策略

Cglib和JDK代理

如果指定了@EnableAspectJAutoProxy(proxyTargetClass = true) 则使用Cglib代理,否则如果目标类实现了接口,则使用JDK动态代理技术,否则使用Cglib来生成代理。

@EnableAspectJAutoProxy

1.通过@EnableAspectJAutoProxy注解的Import注解向IOC容器注册了AnnotationAwareAspectJAutoProxyCreator

@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
//导入了AspectJAutoProxyRegistrar
AspectJAutoProxyRegistrar:向IOC容器注册了AnnotationAwareAspectJAutoProxyCreator 
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
通过ImportBeanDefinitionRegistrar注册

//添加bean  AnnotationAwareAspectJAutoProxyCreator
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);

2.在Bean的后置处理器里面通过AspectJAwareAdvisorAutoProxyCreator的父类创建代理对象

在Spring Bean处理器的AspectJAwareAdvisorAutoProxyCreator创建的代理对象

 Spring AOP 源码学习

3.后置处理器BeanPostProcessor调用AbstractAutoProxyCreator创建代理对象

 Spring AOP 源码学习

调用代理类图

分析调用逻辑之前先上类图,看看Spring 中主要的AOP 组件:

Spring AOP 源码学习

代理对象生成源码

getBean——>AbstractBeanFactory:doGetBean->
AbstractAutowireCapableBeanFactory:createBean->doCreateBean->
initializeBean:applyBeanPostProcessorsAfterInitialization->AbstractAutoProxyCreator :postProcessAfterInitialization
wrapIfNecessary:createProxy->ProxyCreatorSupport:createAopProxy  
 
 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
       // 删除无关代码
        Object exposedObject = bean;

        try {
            this.populateBean(beanName, mbd, instanceWrapper);
            // 创建代理入口,后置处理器 创建代理对象
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }
 
    }

 AbstractAutoProxyCreator

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                  //创建代理
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }

        return bean;
    }
 

 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
             //这里来查找通知 用于确定是否需要创建代理对象 (根据切面的切入点判断当前类是否有通知)
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
             //
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                  //创建代理入口
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }
AbstractAutoProxyCreator

//  AbstractAutoProxyCreator
 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 = new ProxyFactory();
        proxyFactory.copyFrom(this);
        if (!proxyFactory.isProxyTargetClass()) {
            if (this.shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            } else {
                this.evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        this.customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(this.freezeProxy);
        if (this.advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }

       //从工厂里面获取proxyFactory
        return proxyFactory.getProxy(this.getProxyClassLoader());
    }

//ProxyFactory
  public Object getProxy(@Nullable ClassLoader classLoader) {
        return this.createAopProxy().getProxy(classLoader);
    }
//ProxyCreatorSupport
  protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            this.activate();
        }

        return this.getAopProxyFactory().createAopProxy(this);
    }
//DefaultAopProxyFactory
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   //判断我们是否前置指定使用 cglib代理的 ProxyTargetClass
   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.");
      }
      //所有targetCalss是接口 使用jdk
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
         return new JdkDynamicAopProxy(config);
      }
      //动态代理
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      return new JdkDynamicAopProxy(config);
   }
}
//JdkDynamicAopProxy 使用JDK自带的创建代理对象
public Object getProxy(@Nullable ClassLoader classLoader) { 
 Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
 this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
          //调用实际调用创建代理对象
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }
//CglibAopProxy 
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
      try {
      Class<?> rootClass = this.advised.getTargetClass();
      
      // 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 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);
   }
//ObjenesisCglibAopProxy
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
    Class<?> proxyClass = enhancer.createClass();
    Object proxyInstance = null;
    if (objenesis.isWorthTrying()) {
        try {
            proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
        } catch (Throwable var7) {
            logger.debug("Unable to instantiate proxy using Objenesis, falling back to regular proxy construction", var7);
        }
    }

    if (proxyInstance == null) {
        try {
            Constructor<?> ctor = this.constructorArgs != null ? proxyClass.getDeclaredConstructor(this.constructorArgTypes) : proxyClass.getDeclaredConstructor();
            ReflectionUtils.makeAccessible(ctor);
            proxyInstance = this.constructorArgs != null ? ctor.newInstance(this.constructorArgs) : ctor.newInstance();
        } catch (Throwable var6) {
            throw new AopConfigException("Unable to instantiate proxy using Objenesis, and regular proxy instantiation via default constructor fails as well", var6);
        }
    }

    ((Factory)proxyInstance).setCallbacks(callbacks);
    return proxyInstance;
}
代理对象生成源码

相关文章:

  • 2021-12-17
  • 2022-02-01
  • 2021-06-20
  • 2021-11-17
  • 2022-02-24
  • 2021-07-09
  • 2021-08-27
  • 2022-01-11
猜你喜欢
  • 2021-06-08
  • 2021-08-16
  • 2022-12-23
  • 2021-12-08
  • 2022-12-23
  • 2021-05-14
  • 2021-05-17
相关资源
相似解决方案