您现在的位置是:首页 >其他 >spring-transaction源码分析(4)AspectJ和spring-aspects模块网站首页其他

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

xuguofeng2016 2024-06-17 10:26:13
简介spring-transaction源码分析(4)AspectJ和spring-aspects模块

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

java -jar aspectj-1.9.6.jar

示例安装到D:appaspectj1.9目录下。

基础示例

目录结构

aspectj1.9
  |-- bin
    |-- ajc
    |-- ajc.bat
  |-- doc
  |-- lib
    |-- aspectjrt.jar
    |-- aspectjtools.jar
    |-- aspectjweaver.jar

官方示例

cd D:appaspectj1.9docexamples

set CLASSPATH="D:appaspectj1.9libaspectjrt.jar"
set Path=D:appaspectj1.9bin;%Path%

ajc -argfile tracing/tracelib.lst -outjar tracelib.jar
ajc -aspectpath tracelib.jar -argfile tracing/notrace.lst -outjar tracedapp.jar

java -classpath "%CLASSPATH%;tracedapp.jar;tracelib.jar" tracing.ExampleMain

spring-aspects模块

AdviceMode.ASPECTJ模式

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

此时需要:

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

AnnotationTransactionAspect

这个类在spring-aspects模块中。

AnnotationTransactionAspect.aj文件:

public aspect AnnotationTransactionAspect extends AbstractTransactionAspect {

	public AnnotationTransactionAspect() {
		super(new AnnotationTransactionAttributeSource(false));
	}

	private pointcut executionOfAnyPublicMethodInAtTransactionalType() :
		execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *);

	private pointcut executionOfTransactionalMethod() :
		execution(@Transactional * *(..));

	protected pointcut transactionalMethodExecution(Object txObject) :
		(executionOfAnyPublicMethodInAtTransactionalType() || executionOfTransactionalMethod() ) && 
            this(txObject);
}

AbstractTransactionAspect.aj文件:

public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport implements DisposableBean {

	protected AbstractTransactionAspect(TransactionAttributeSource tas) {
		setTransactionAttributeSource(tas);
	}

	@Override
	public void destroy() {
		clearTransactionManagerCache();
	}

	@SuppressAjWarnings("adviceDidNotMatch")
	Object around(final Object txObject): transactionalMethodExecution(txObject) {
		MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		try {
			return invokeWithinTransaction(methodSignature.getMethod(), txObject.getClass(), 
                                           new InvocationCallback() {
				public Object proceedWithInvocation() throws Throwable {
					return proceed(txObject);
				}
			});
		} catch (RuntimeException | Error ex) {
			throw ex;
		} catch (Throwable thr) {
			Rethrower.rethrow(thr);
			throw new IllegalStateException("Should never get here", thr);
		}
	}

	protected abstract pointcut transactionalMethodExecution(Object txObject);
}

这两个类使用aspectj语法声明了事务切入点和环绕通知。

该模块在构建时会使用aspectj的ajc编译器将aj文件编译成class文件。

参考资料

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

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。