spring-transaction源码分析(4)AspectJ和spring-aspects模块

打印 上一主题 下一主题

主题 616|帖子 616|积分 1848

AspectJ是Java语言实现的一个面向切面编程的扩展库,能够基于一定的语法编写Aspect代码,使用ajc编译器将其编译成.class文件,之后在Java程序编写或加载时将Aspect逻辑嵌入到指定的切面。
安装AspectJ

下载AspectJ

到官网下载安装包:
http://www.eclipse.org/downloads/download.php?file=/tools/aspectj/aspectj-1.9.6.jar
安装AspectJ
  1. java -jar aspectj-1.9.6.jar
复制代码
示例安装到D:\app\aspectj1.9目录下。
基础示例

目录结构
  1. aspectj1.9
  2.   |-- bin
  3.     |-- ajc
  4.     |-- ajc.bat
  5.   |-- doc
  6.   |-- lib
  7.     |-- aspectjrt.jar
  8.     |-- aspectjtools.jar
  9.     |-- aspectjweaver.jar
复制代码
官方示例
  1. cd D:\app\aspectj1.9\doc\examples
  2. set CLASSPATH="D:\app\aspectj1.9\lib\aspectjrt.jar"
  3. set Path=D:\app\aspectj1.9\bin;%Path%
  4. ajc -argfile tracing/tracelib.lst -outjar tracelib.jar
  5. ajc -aspectpath tracelib.jar -argfile tracing/notrace.lst -outjar tracedapp.jar
  6. java -classpath "%CLASSPATH%;tracedapp.jar;tracelib.jar" tracing.ExampleMain
复制代码
spring-aspects模块

AdviceMode.ASPECTJ模式

当EnableTransactionManagement注解的mode属性设置为AdviceMode.ASPECTJ时,将不会再使用spring aop生成事务代理,而是使用AspectJ代理,即装配AnnotationTransactionAspect对象,AnnotationTransactionAspect是一个原生AspectJ组件,该组件使用AspectJ在类加载阶段为目标方法嵌入事务拦截逻辑以实现事务管理。
此时需要:

  • 添加spring-aspects依赖
  • 添加-javaagent:path/to/aspectjweaver.jar启动参数
AnnotationTransactionAspect

这个类在spring-aspects模块中。
AnnotationTransactionAspect.aj文件:
  1. public aspect AnnotationTransactionAspect extends AbstractTransactionAspect {
  2.         public AnnotationTransactionAspect() {
  3.                 super(new AnnotationTransactionAttributeSource(false));
  4.         }
  5.         private pointcut executionOfAnyPublicMethodInAtTransactionalType() :
  6.                 execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *);
  7.         private pointcut executionOfTransactionalMethod() :
  8.                 execution(@Transactional * *(..));
  9.         protected pointcut transactionalMethodExecution(Object txObject) :
  10.                 (executionOfAnyPublicMethodInAtTransactionalType() || executionOfTransactionalMethod() ) &&
  11.             this(txObject);
  12. }
复制代码
AbstractTransactionAspect.aj文件:
  1. public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport implements DisposableBean {
  2.         protected AbstractTransactionAspect(TransactionAttributeSource tas) {
  3.                 setTransactionAttributeSource(tas);
  4.         }
  5.         @Override
  6.         public void destroy() {
  7.                 clearTransactionManagerCache();
  8.         }
  9.         @SuppressAjWarnings("adviceDidNotMatch")
  10.         Object around(final Object txObject): transactionalMethodExecution(txObject) {
  11.                 MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
  12.                 // Adapt to TransactionAspectSupport's invokeWithinTransaction...
  13.                 try {
  14.                         return invokeWithinTransaction(methodSignature.getMethod(), txObject.getClass(),
  15.                                            new InvocationCallback() {
  16.                                 public Object proceedWithInvocation() throws Throwable {
  17.                                         return proceed(txObject);
  18.                                 }
  19.                         });
  20.                 } catch (RuntimeException | Error ex) {
  21.                         throw ex;
  22.                 } catch (Throwable thr) {
  23.                         Rethrower.rethrow(thr);
  24.                         throw new IllegalStateException("Should never get here", thr);
  25.                 }
  26.         }
  27.         protected abstract pointcut transactionalMethodExecution(Object txObject);
  28. }
复制代码
这两个类使用aspectj语法声明了事务切入点和环绕通知。
该模块在构建时会使用aspectj的ajc编译器将aj文件编译成class文件。
参考资料

https://www.eclipse.org/aspectj/docs.php

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

滴水恩情

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表