Spring AOP 详解及@Trasactional

Spring AOP 详解

AOP基础

AOP: Aspect Oriented Program, 面向切面编程。解耦(组织结构调整)、增强(扩展)。

AOP术语

术语

说明

Aspect(切面)

横切于系统的连接点实现特定功能的类

JoinPoint(连接点)

系统执行的某个动态阶段,如对象操作、方法调用等

Pointcut(切点)

定义了Aspect发生作用的切入特征

Advice(增强)

在连接点执行的增强操作

Target Object(目标对象)

Advice作用对象、被增强对象

Proxy(代理)

为了实施增强,动态创建的对象。

Weaving(织入)

构建可以针对目标对象实施增强行为的代理对象的基础过程。

AOP Aliance

AOP Aliance: AOP联盟,定义了AOP的基础规范。

AOP JavaAPIDoc 网址: Generated Documentation (Untitled)

AOP 官方白皮书地址:https://aopalliance.sourceforge.net/white_paper/white_paper.pdf

图1 Spring AOP中的AOP Aliance 基本接口

AspectJ

AsprctJ 是Java社区里最完整最流行的AOP框架。

官网: AspectJ Documentation | The Eclipse Foundation

AspectJ提供了完整的AOP解决方案,支持以下三种织入时机:

  • compile-time:编译期织入,编译出包含织入代码的 .class 文件
  • post-compile:编译后织入,增强已经编译出来的类,如我们要增强依赖的 jar 包中的某个类的某个方法
  • load-time:在 JVM 进行类加载的时候进行织入

Spring AOP 和 AspectJ

Spring AOP: 为Spring IoC上提供的AOP实现,应用于Spring Bean容器管理的,以及Spring 框架其他技术,如Spring Transactional

AspectJ: 提供完整的AOP解决方案。它比Spring AOP更强大,但也更复杂。还值得注意的是,AspectJ可以应用于所有域对象。

Spring AOP

AspectJ

用纯Java实现

使用Java编程语言的扩展实现

无需单独的编译过程

除非设置了LTW,否则需要AspectJ编译器(ajc)

仅需运行时编织

运行时编织不可用。支持编译时,后编译和加载时编织

不足–仅支持方法级编织

更强大–可以编织字段,方法,构造函数,静态初始值设定项,最终类/方法等…

只能在Spring容器管理的bean上实现

可以在所有领域对象上实施

仅支持方法执行切入点

支持所有切入点

代理是针对目标对象创建的,并且方面已应用于这些代理

在应用程序执行之前(运行时之前)将方面直接编织到代码中

比AspectJ慢得多

更好的性能

易于学习和应用

比Spring AOP复杂得多

Spring AOP代理的生成

Cglib代理和JDK动态代理。

JDK 动态代理是JDK内置的动态代理工具,底层原理是反射机制,为目标接口创建代理,动态代理类需要实现InvocationHandler接口。代理实现原理是通过实现被代理类的接口,被代理对象由InvocationHandler进行包装调用。

public interface InvocationHandler {

   /**

     * @param proxy 包装的代理对象

     * @param method 调用的方法

     * @param args 调用方法参数

    */

    public Object invoke(Object proxy, Method method, Object[] args)

        throws Throwable;

}

public static <T> T getProxyObject(T object,

                               InvocationHandler h) {

return (T) Proxy.newProxyInstance(object.getClass().getClassLoader(),

                        object.getClass().getInterfaces(), h);

}

try {

    super.h.invoke(this, m3, (Object[])null);

} catch (RuntimeException | Error var2) {

    throw var2;

} catch (Throwable var3) {

    throw new UndeclaredThrowableException(var3);

}

Cglib底层原理通过字节码处理框架ASM修改类的字节码生成继承方法的子类,通过修改字节码生成子类代理直接代替实体类,需要实现MethodInterceptor接口。 继承方式意味着不能对final修饰的类、final修饰的方法、私有方法进行代理。

public interface MethodInterceptor

extends Callback

{

    /**

     * 拦截方法逻辑

     *

     * @param o           被增强的对象

     * @param method      被增强的方法

     * @param args        方法的参数

     * @param methodProxy 方法的代理对象

     * @return 方法返回值

     */

    public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,

                               MethodProxy proxy) throws Throwable;

}

Enhancer.create(object.getClass(), methodInterceptor)

Spring AOP 创建代理过程

下面介绍了Spring Aop支持AspectJ注解的代理创建过程, 其他注解的AOP类似,只是通过不同的扩展点来创建代理对象,如ProxyFactoryBean或BeanPostProcessor。

@EnableAspectJAutoProxy

项目为启用AspectJ的Spring-AOP,通常会再配置文件中加上@EnableAspectJAutoProxy

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Import(AspectJAutoProxyRegistrar.class)

public @interface EnableAspectJAutoProxy {

         boolean proxyTargetClass() default false;

         boolean exposeProxy() default false;

}

@Import(AspectJAutoProxyRegistrar.class)

@Import 注解包含一个实现了ImportBeanDefinitionRegistrar的类, 注册重要的Bean用于后续Bean初始化。AspectJAutoProxyRegistrar

public void registerBeanDefinitions(

                          AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

                  AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

                  AnnotationAttributes enableAspectJAutoProxy =

                                   AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);

                  if (enableAspectJAutoProxy != null) {

                          if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {

                                   AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);

                          }

                          if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {

                                   AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);

                          }

                  }

         }

AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator负责创建AOP代理,实现了SmartInstantiationAwareBeanPostProcessor(InstantiationAwareBeanPostProcessor) 接口,核心创建逻辑在postProcessBeforeInstantiation实现中。

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {

         //缓存Bean类和名称,避免重复处理

         Object cacheKey = getCacheKey(beanClass, beanName);

         if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {

                  if (this.advisedBeans.containsKey(cacheKey)) {

                          return null;

                  }

                  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.

         TargetSource targetSource = getCustomTargetSource(beanClass, beanName);

         if (targetSource != null) {

                  if (StringUtils.hasLength(beanName)) {

                          this.targetSourcedBeans.add(beanName);

                  }

                  //检查AOP相关配置是否作用在Bean上,如果不匹配这里返回空, 再下一步创建proxy将返回空

                  Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);

                  Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);

                  this.proxyTypes.put(cacheKey, proxy.getClass());

                  return proxy;

         }

         return null;

}

检查是否该创建Bean对象的逻辑在AopUtils.canApply方法。

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {

         if (advisor instanceof IntroductionAdvisor) {

                  return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);

         }

         else if (advisor instanceof PointcutAdvisor) {

                  PointcutAdvisor pca = (PointcutAdvisor) advisor;

                  return canApply(pca.getPointcut(), targetClass, hasIntroductions);

         }

         else {

                  // It doesn't have a pointcut so we assume it applies.

                  return true;

         }

}

AopProxyFactory

继续跟进代码 最终由AopProxyFactory来创建。 AopProxyFactory 调用AopProxy接口的getProxy方法创建代理对象。 AopProxy有两个实现:JdkDynamicAopProxy和ObjenesisCglibAopProxy对应于JDK动态代理和Cglib代理实现。

选择AopProxy的代码如下:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

                  if (!NativeDetector.inNativeImage() &&

                                   (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) || ClassUtils.isLambdaClass(targetClass)) {

                                   return new JdkDynamicAopProxy(config);

                          }

                          return new ObjenesisCglibAopProxy(config);

                  }

                  else {

                          return new JdkDynamicAopProxy(config);

                  }

         }

具体创建代理的代码为Cglib和JDK代理的使用方法。如JdkDynamicAopProxy的getProxy()代码如下:

public Object getProxy(@Nullable ClassLoader classLoader) {

                  if (logger.isTraceEnabled()) {

                          logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());

                  }

                  return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);

         }

Spring AOP切面相关抽象及解析过程

主要抽象
Advice

Org.aopalliance.aop.Advice: AOP联盟的Advice接口,代表增强入口,其实现包括Interceptors或其他任何类型的Advice。

Org.aopalliance.intercept.interceptor: : 指可以针对Joint事件进行拦截的拦截器。

MethodInterceptor:对接口调用的拦截

public interface MethodInterceptor extends Interceptor {

  @Nullable

  Object invoke(@Nonnull MethodInvocation invocation) throws Throwable;

}

ConstructorInterceptor: 对对象构造的拦截

DynamicIntroductionAdvice:支持在Advice上实现附加接口。

public interface DynamicIntroductionAdvice extends Advice {

  boolean implementsInterface(Class<?> intf);

}

IntroductionInterceptor extends MethodInterceptor, DynamicIntroductionAdvice : 通过Interceptor实现DynamicIntroductionAdvice。

       IntroductionInfo: 描述引入接口的信息

MethodBeforeAdvice: 在方法调用之前执行的Advice

AfterReturningAdvice: 在方法返回之后执行的Advice

ThrowsAdvice: 异常抛出后执行的Advice

       public void afterThrowing(Exception ex)

       public void afterThrowing(RemoteException)

       public void afterThrowing(Method method, Object[] args, Object target, Exception ex)

       public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)

ClassFilter

ClassFilter: 负责检查一个pointcut 或则 introduction时候和目标类匹配

public interface ClassFilter {

  boolean matches(Class<?> clazz);

}

MethodMatcher

MethodMatcher:负责检查方法是否匹配Advice

public interface MethodMatcher {

         boolean matches(Method method, Class<?> targetClass);

         boolean isRuntime();

         boolean matches(Method method, Class<?> targetClass, Object... args);

}

Advisor

Advisor: 持有AOP Advice信息的接口,

public interface Advisor {

  //返回切面的Advice信息, Advice指interceptor、before advice 、throw advice等

  Advice getAdvice();

  //Advisor是否共享

  boolean isPerInstance();

}

AdvisorChainFactory

实现类DefaultAdvisorChainFactory,接口方法getInterceptorsAndDynamicInterceptionAdvice返回指定方法的Advice链(增强链),当执行代理对象时根据这里放回的Advice链进行增强。

for (Advisor advisor : advisors) {

         if (advisor instanceof PointcutAdvisor) {

                  // Add it conditionally.

                  PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;

                  if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {

                          MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();

                          boolean match;

                          if (mm instanceof IntroductionAwareMethodMatcher) {

                                   if (hasIntroductions == null) {

                                            hasIntroductions = hasMatchingIntroductions(advisors, actualClass);

                                   }

                                   match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);

                          }

                          else {

                                   match = mm.matches(method, actualClass);

                          }

                          if (match) {

                                   MethodInterceptor[] interceptors = registry.getInterceptors(advisor);

                                   if (mm.isRuntime()) {

                                            // Creating a new object instance in the getInterceptors() method

                                            // isn't a problem as we normally cache created chains.

                                            for (MethodInterceptor interceptor : interceptors) {

                                                     interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));

                                            }

                                   }

                                   else {

                                            interceptorList.addAll(Arrays.asList(interceptors));

                                   }

                          }

                  }

         }

         else if (advisor instanceof IntroductionAdvisor) {

                  IntroductionAdvisor ia = (IntroductionAdvisor) advisor;

                  if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {

                          Interceptor[] interceptors = registry.getInterceptors(advisor);

                          interceptorList.addAll(Arrays.asList(interceptors));

                  }

         }

         else {

                  Interceptor[] interceptors = registry.getInterceptors(advisor);

                  interceptorList.addAll(Arrays.asList(interceptors));

         }

}

Advised

Advised是AOP的配置信息, AOP代理的创建时基于Advised提供的Advise及Advisor信息创建。

如:Advised接口提供了Advisor的管理方法(get/addAdvisors)。

AopContext

AopContext 提供AOP线程上线文的。

ThreadLocal<Object> currentProxy = new NamedThreadLocal<>("Current AOP proxy");

ProxyConfig

AOP 代理创建的配置类, 提取公共父类保证代理的一致性。

ProxyConfig作为AOP代理创建代理对象的一个基础类,其实现展示了几种代理的实现机制。

BeanFactoryAware+BeanPostProcessor方式

AbstractAdvisingBeanPostProcessor及其子类使用该模式进行框架初始化, 该模式针对特定切面,如Async。通过setBeanFactory方法初始Advisor信息, 并在postProcessAfterInitialization方法中创建代理对象。

AsyncAnnotationBeanPostProcessor

@Override

public void setBeanFactory(BeanFactory beanFactory) {

         super.setBeanFactory(beanFactory);

         AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler);

         if (this.asyncAnnotationType != null) {

                  advisor.setAsyncAnnotationType(this.asyncAnnotationType);

         }

         advisor.setBeanFactory(beanFactory);

         this.advisor = advisor;

}

@Override

public Object postProcessAfterInitialization(Object bean, String beanName) {

         ......

         if (isEligible(bean, beanName)) {

                  ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);

                  if (!proxyFactory.isProxyTargetClass()) {

                          evaluateProxyInterfaces(bean.getClass(), proxyFactory);

                  }

                  proxyFactory.addAdvisor(this.advisor);

                  customizeProxyFactory(proxyFactory);

                  // Use original ClassLoader if bean class not locally loaded in overriding class loader

                  ClassLoader classLoader = getProxyClassLoader();

                  if (classLoader instanceof SmartClassLoader && classLoader != bean.getClass().getClassLoader()) {

                          classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();

                  }

                  return proxyFactory.getProxy(classLoader);

         }

         // No proxy needed.

         return bean;

}

protected boolean isEligible(Class<?> targetClass) {

         Boolean eligible = this.eligibleBeans.get(targetClass);

         if (eligible != null) {

                  return eligible;

         }

         if (this.advisor == null) {

                  return false;

         }

         eligible = AopUtils.canApply(this.advisor, targetClass);

         this.eligibleBeans.put(targetClass, eligible);

         return eligible;

}

基于SmartInstantiationAwareBeanPostProcessor的AutoProxyCreator

AOP关于AspectJ注解的支持是基于该模式创建, 该模式的特点是: 1. 支持各种不同功能的切面增强。 2. 代理对象负责创建目标对象,支持目标对象的延迟创建。

基于postProcessBeforeInstantiation接口创建。

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {

         Object cacheKey = getCacheKey(beanClass, beanName);

         // 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.

         TargetSource targetSource = getCustomTargetSource(beanClass, beanName);

         if (targetSource != null) {

                  if (StringUtils.hasLength(beanName)) {

                          this.targetSourcedBeans.add(beanName);

                  }

                  Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);

                  Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);

                  this.proxyTypes.put(cacheKey, proxy.getClass());

                  return proxy;

         }

         return null;

}

相关代码见AbstractAutoProxyCreator及其子类, 在Spring AOP创建章节中详细介绍。

初始化核心调用栈示例:

getTransactionAttribute:93, AbstractFallbackTransactionAttributeSource (org.springframework.transaction.interceptor)

matches:42, TransactionAttributeSourcePointcut (org.springframework.transaction.interceptor)

canApply:251, AopUtils (org.springframework.aop.support)

canApply:288, AopUtils (org.springframework.aop.support)

findAdvisorsThatCanApply:320, AopUtils (org.springframework.aop.support)

findAdvisorsThatCanApply:126, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)

findEligibleAdvisors:95, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)

getAdvicesAndAdvisorsForBean:76, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)

wrapIfNecessary:352, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)

postProcessAfterInitialization:304, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)

基于FactoryBean模式创建代理

@Transaction及@Cache注解的创建模式

AbstractSingletonProxyFactoryBean

public void afterPropertiesSet() {

         ProxyFactory proxyFactory = new ProxyFactory();

         if (this.preInterceptors != null) {

                  for (Object interceptor : this.preInterceptors) {

                          proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));

                  }

         }

         // Add the main interceptor (typically an Advisor).

         proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));

         if (this.postInterceptors != null) {

                  for (Object interceptor : this.postInterceptors) {

                          proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));

                  }

         }

         proxyFactory.copyFrom(this);

         TargetSource targetSource = createTargetSource(this.target);

         proxyFactory.setTargetSource(targetSource);

         if (this.proxyInterfaces != null) {

                  proxyFactory.setInterfaces(this.proxyInterfaces);

         }

         else if (!isProxyTargetClass()) {

                  // Rely on AOP infrastructure to tell us what interfaces to proxy.

                  Class<?> targetClass = targetSource.getTargetClass();

                  if (targetClass != null) {

                          proxyFactory.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));

                  }

         }

         postProcessProxyFactory(proxyFactory);

         this.proxy = proxyFactory.getProxy(this.proxyClassLoader);

}

protected Object createMainInterceptor() {

         this.transactionInterceptor.afterPropertiesSet();

         if (this.pointcut != null) {

                  return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor);

         }

         else {

                  // Rely on default pointcut.

                  return new TransactionAttributeSourceAdvisor(this.transactionInterceptor);

         }

}

//TransactionProxyFactoryBean

AopProxy

AOP 代理接口实现类包括Cglib和Jdk动态代理

      

AopProxyFactory

AopProxy工厂接口,负责创建AopProxy对象。实现类是DefaultAopProxyFactory

                  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) || ClassUtils.isLambdaClass(targetClass)) {

                          return new JdkDynamicAopProxy(config);

                  }

                  return new ObjenesisCglibAopProxy(config);

注解信息的解析(Advised对象的创建)

Advised对象的解析过程同ProxyConfig章节介绍的代理对象过程类似,同样是三种模式的解析过程。

AbstractAdvisingBeanPostProcessor

AbstractAdvisingBeanPostProcessor 针对特定注解创建代理对象模式。扩展点BeanPostProcessor 的postProcessAfterInitialization方法中检查注解是否作用在Bean上,如是则创建代理。

if (isEligible(bean, beanName)) {

         ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);

         if (!proxyFactory.isProxyTargetClass()) {

                  evaluateProxyInterfaces(bean.getClass(), proxyFactory);

         }

         proxyFactory.addAdvisor(this.advisor);

         customizeProxyFactory(proxyFactory);

         // Use original ClassLoader if bean class not locally loaded in overriding class loader

         ClassLoader classLoader = getProxyClassLoader();

         if (classLoader instanceof SmartClassLoader && classLoader != bean.getClass().getClassLoader()) {

                  classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();

         }

         return proxyFactory.getProxy(classLoader);

}

AbstractSingletonProxyFactoryBean

基于FactoryBean机制,对通过XML配置的FactoryBean,针对目标Bean解析所得Advicsed对象。

<bean id="target" class="org.springframework.beans.testfixture.beans.DerivedTestBean" lazy-init="true">

         <property name="name"><value>custom</value></property>

         <property name="age"><value>666</value></property>

         <property name="spouse"><ref bean="targetDependency"/></property>

</bean>

<bean id="baseProxyFactory" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"

           abstract="true">

         <property name="transactionManager"><ref bean="mockMan"/></property>

         <property name="transactionAttributes">

                  <props>

                          <prop key="s*">PROPAGATION_MANDATORY</prop>

                          <prop key="setAg*">  PROPAGATION_REQUIRED  ,  readOnly  </prop>

                          <prop key="set*">PROPAGATION_SUPPORTS</prop>

                  </props>

         </property>

</bean>

<bean id="proxyFactory2Cglib" parent="baseProxyFactory">

         <property name="proxyTargetClass"><value>true</value></property>

         <property name="target"><ref bean="target"/></property>

</bean>

public void afterPropertiesSet() {

         ProxyFactory proxyFactory = new ProxyFactory();

         if (this.preInterceptors != null) {

                  for (Object interceptor : this.preInterceptors) {

                          proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));

                  }

         }

         // Add the main interceptor (typically an Advisor).

         proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));

         if (this.postInterceptors != null) {

                  for (Object interceptor : this.postInterceptors) {

                          proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));

                  }

         }

         proxyFactory.copyFrom(this);

         TargetSource targetSource = createTargetSource(this.target);

         proxyFactory.setTargetSource(targetSource);

         if (this.proxyInterfaces != null) {

                  proxyFactory.setInterfaces(this.proxyInterfaces);

         }

         else if (!isProxyTargetClass()) {

                  // Rely on AOP infrastructure to tell us what interfaces to proxy.

                  Class<?> targetClass = targetSource.getTargetClass();

                  if (targetClass != null) {

                          proxyFactory.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));

                  }

         }

         postProcessProxyFactory(proxyFactory);

         this.proxy = proxyFactory.getProxy(this.proxyClassLoader);

}

ProxyFactoryBean

基于ProxyFactoryBean创建的代理的对象,在获取对象时会检查是否需要解析和创建AOP 的代理。

public Object getObject() throws BeansException {

         initializeAdvisorChain();

         if (isSingleton()) {

                  return getSingletonInstance();

         }

         else {

                  if (this.targetName == null) {

                          logger.info("Using non-singleton proxies with singleton targets is often undesirable. " +

                                            "Enable prototype proxies by setting the 'targetName' property.");

                  }

                  return newPrototypeInstance();

         }

}

Spring AOP的执行

JDK代理执行代码

JdkDynamicAopProxy 执行了JDK动态代理的InvocationHandler接口, 执行入口就是JdkDynamicAopProxy的invoke方法。

流程:

  1. 获取该方法匹配的Advice

// Get the interception chain for this method.

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

查找匹配实现为接口AdvisorChainFactory接口的实现类:DefaultAdvisorChainFactory。

public interface AdvisorChainFactory {

         /**

          * Determine a list of {@link org.aopalliance.intercept.MethodInterceptor} objects

          * for the given advisor chain configuration.

          * @param config the AOP configuration in the form of an Advised object

          * @param method the proxied method

          * @param targetClass the target class (may be {@code null} to indicate a proxy without

          * target object, in which case the method's declaring class is the next best option)

          * @return a List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)

          */

         List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass);

}

解析相应的MethodInterceptor接口实现或适配AOP 联盟的语言成为MethodInterceptor接口。

如:MethodBeforeAdviceInterceptor代码如下:

public Object invoke(MethodInvocation mi) throws Throwable {

         this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());

         return mi.proceed();

}

  1. 执行

// We need to create a method invocation...

MethodInvocation invocation =  new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);

// Proceed to the joinpoint through the interceptor chain.

retVal = invocation.proceed();

  1. ReflectiveMethodInvocation 处理方法

public Object proceed() throws Throwable {

                  // We start with an index of -1 and increment early.

                  if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {

                          return invokeJoinpoint();

                  }

                  Object interceptorOrInterceptionAdvice =

                                   this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

                  if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {

                          // Evaluate dynamic method matcher here: static part will already have

                          // been evaluated and found to match.

                          InterceptorAndDynamicMethodMatcher dm =

                                            (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;

                          Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());

                          if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {

                                   return dm.interceptor.invoke(this);

                          }

                          else {

                                   // Dynamic matching failed.

                                   // Skip this interceptor and invoke the next in the chain.

                                   return proceed();

                          }

                  }

                  else {

                          // It's an interceptor, so we just invoke it: The pointcut will have

                          // been evaluated statically before this object was constructed.

                          return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

                  }

         }

AopContext

AopContext类可以再代理类执行过程中获取到代理对象, 通过代理对象可以保证基于AOP增强的特性得到执行,从而解决直接this.xxx调用直接执行被代理对象的方法,造成增强实效。

Spring Aop 应用-@Transactional

       Spring Transaction就是基于Spring AOP机制实现的事务。

解析@Transactionnal

       事务的拦截逻辑实现主要在TransactionInterceptor类中, 如果通过XML文件配置的TransactionProxyFactoryBean创建代理对象,则在FactoryBean的afterProperties方法中创建Advisor生成proxyFactory对象(见上面章节)。

对于基于注解的Transaction注解解析在于TransactionAttributeSourcePointcut由AOP框架触发解析判断某个方法是否满足Transactional注解。

解析逻辑代码如下:

@Nullable

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {

         // Don't allow non-public methods, as configured.

         if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {

                  return null;

         }

         // The method may be on an interface, but we need attributes from the target class.

         // If the target class is null, the method will be unchanged.

         Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

         // First try is the method in the target class.

         TransactionAttribute txAttr = findTransactionAttribute(specificMethod);

         if (txAttr != null) {

                  return txAttr;

         }

         // Second try is the transaction attribute on the target class.

         txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());

         if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {

                  return txAttr;

         }

         if (specificMethod != method) {

                  // Fallback is to look at the original method.

                  txAttr = findTransactionAttribute(method);

                  if (txAttr != null) {

                          return txAttr;

                  }

                  // Last fallback is the class of the original method.

                  txAttr = findTransactionAttribute(method.getDeclaringClass());

                  if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {

                          return txAttr;

                  }

         }

         return null;

}

TransactionInterceptor

事务执行逻辑实现与TransactionInterceptor

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {

// Standard transaction demarcation with getTransaction and commit/rollback calls.

TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

Object retVal;

try {

         // This is an around advice: Invoke the next interceptor in the chain.

         // This will normally result in a target object being invoked.

         retVal = invocation.proceedWithInvocation();

}

catch (Throwable ex) {

         // target invocation exception

         completeTransactionAfterThrowing(txInfo, ex);

         throw ex;

}

finally {

         cleanupTransactionInfo(txInfo);

}

if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {

         // Set rollback-only in case of Vavr failure matching our rollback rules...

         TransactionStatus status = txInfo.getTransactionStatus();

         if (status != null && txAttr != null) {

                  retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);

         }

}

commitTransactionAfterReturning(txInfo);

return retVal;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值