diff --git a/spring-aspects/src/main/java/org/springframework/transaction/aspectj/AbstractTransactionAspect.aj b/spring-aspects/src/main/java/org/springframework/transaction/aspectj/AbstractTransactionAspect.aj deleted file mode 100644 index 782ca35e0777..000000000000 --- a/spring-aspects/src/main/java/org/springframework/transaction/aspectj/AbstractTransactionAspect.aj +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.transaction.aspectj; - -import org.aspectj.lang.annotation.SuppressAjWarnings; -import org.aspectj.lang.reflect.MethodSignature; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.transaction.interceptor.TransactionAspectSupport; -import org.springframework.transaction.interceptor.TransactionAttributeSource; - -/** - * Abstract superaspect for AspectJ transaction aspects. Concrete - * subaspects will implement the {@code transactionalMethodExecution()} - * pointcut using a strategy such as Java 5 annotations. - * - *
Suitable for use inside or outside the Spring IoC container. - * Set the "transactionManager" property appropriately, allowing - * use of any transaction implementation supported by Spring. - * - *
NB: If a method implements an interface that is itself
- * transactionally annotated, the relevant Spring transaction attribute
- * will not be resolved. This behavior will vary from that of Spring AOP
- * if proxying an interface (but not when proxying a class). We recommend that
- * transaction annotations should be added to classes, rather than business
- * interfaces, as they are an implementation detail rather than a contract
- * specification validation.
- *
- * @author Rod Johnson
- * @author Ramnivas Laddad
- * @author Juergen Hoeller
- * @since 2.0
- */
-public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport implements DisposableBean {
-
-	/**
-	 * Construct the aspect using the given transaction metadata retrieval strategy.
-	 * @param tas TransactionAttributeSource implementation, retrieving Spring
-	 * transaction metadata for each joinpoint. Implement the subclass to pass in
-	 * {@code null} if it is intended to be configured through Setter Injection.
-	 */
-	protected AbstractTransactionAspect(TransactionAttributeSource tas) {
-		setTransactionAttributeSource(tas);
-	}
-
-	@Override
-	public void destroy() {
-		// An aspect is basically a singleton -> cleanup on destruction
-		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);
-		}
-	}
-
-	/**
-	 * Concrete subaspects must implement this pointcut, to identify
-	 * transactional methods. For each selected joinpoint, TransactionMetadata
-	 * will be retrieved using Spring's TransactionAttributeSource interface.
-	 */
-	protected abstract pointcut transactionalMethodExecution(Object txObject);
-
-
-	/**
-	 * Ugly but safe workaround: We need to be able to propagate checked exceptions,
-	 * despite AspectJ around advice supporting specifically declared exceptions only.
-	 */
-	private static class Rethrower {
-
-		public static void rethrow(final Throwable exception) {
-			class CheckedExceptionRethrower When using this aspect, you must annotate the implementation class
- * (and/or methods within that class), not the interface (if any) that
- * the class implements. AspectJ follows Java's rule that annotations on
- * interfaces are not inherited.
- *
- *  An @Transactional annotation on a class specifies the default transaction
- * semantics for the execution of any public operation in the class.
- *
- *  An @Transactional annotation on a method within the class overrides the
- * default transaction semantics given by the class annotation (if present).
- * Any method may be annotated (regardless of visibility). Annotating
- * non-public methods directly is the only way to get transaction demarcation
- * for the execution of such operations.
- *
- * @author Rod Johnson
- * @author Ramnivas Laddad
- * @author Adrian Colyer
- * @since 2.0
- * @see org.springframework.transaction.annotation.Transactional
- */
-public aspect AnnotationTransactionAspect extends AbstractTransactionAspect {
-
-	public AnnotationTransactionAspect() {
-		super(new AnnotationTransactionAttributeSource(false));
-	}
-
-	/**
-	 * Matches the execution of any public method in a type with the Transactional
-	 * annotation, or any subtype of a type with the Transactional annotation.
-	 */
-	private pointcut executionOfAnyPublicMethodInAtTransactionalType() :
-		execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *);
-
-	/**
-	 * Matches the execution of any method with the Transactional annotation.
-	 */
-	private pointcut executionOfTransactionalMethod() :
-		execution(@Transactional * *(..));
-
-	/**
-	 * Definition of pointcut from super aspect - matched join points
-	 * will have Spring transaction management applied.
-	 */
-	protected pointcut transactionalMethodExecution(Object txObject) :
-		(executionOfAnyPublicMethodInAtTransactionalType() || executionOfTransactionalMethod() ) && this(txObject);
-
-}
diff --git a/spring-aspects/src/main/java/org/springframework/transaction/aspectj/AnnotationTransactionAspect.java b/spring-aspects/src/main/java/org/springframework/transaction/aspectj/AnnotationTransactionAspect.java
new file mode 100644
index 000000000000..2a40fbe2583c
--- /dev/null
+++ b/spring-aspects/src/main/java/org/springframework/transaction/aspectj/AnnotationTransactionAspect.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2002-2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.transaction.aspectj;
+
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.annotation.RequiredTypes;
+import org.aspectj.lang.annotation.SuppressAjWarnings;
+import org.aspectj.lang.reflect.MethodSignature;
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+
+/**
+ * Concrete AspectJ transaction aspect using Spring's
+ * {@link org.springframework.transaction.annotation.Transactional} annotation.
+ *
+ *  When using this aspect, you must annotate the implementation class
+ * (and/or methods within that class), not the interface (if any) that
+ * the class implements. AspectJ follows Java's rule that annotations on
+ * interfaces are not inherited.
+ *
+ *  An @Transactional annotation on a class specifies the default transaction
+ * semantics for the execution of any public operation in the class.
+ *
+ *  An @Transactional annotation on a method within the class overrides the
+ * default transaction semantics given by the class annotation (if present).
+ * Any method may be annotated (regardless of visibility). Annotating
+ * non-public methods directly is the only way to get transaction demarcation
+ * for the execution of such operations.
+ *
+ * @author Rod Johnson
+ * @author Ramnivas Laddad
+ * @author Adrian Colyer
+ * @author Joshua Chen
+ * @since 2.0
+ * @see org.springframework.transaction.annotation.Transactional
+ */
+@Aspect
+@RequiredTypes("org.springframework.transaction.annotation.Transactional")
+public class AnnotationTransactionAspect extends TransactionAspectSupport implements DisposableBean {
+
+	/**
+	 * Construct the aspect using the default transaction metadata retrieval strategy.
+	 */
+	public AnnotationTransactionAspect() {
+		new AnnotationTransactionAttributeSource(false);  // Use AnnotationTransactionAttributeSource
+	}
+
+	@Override
+	public void destroy() {
+		// An aspect is basically a singleton -> cleanup on destruction
+		clearTransactionManagerCache();
+	}
+
+	/**
+	 * Around advice: Intercepts transactional method execution.
+	 * @param joinPoint proceedingJoinPoint context for the joinpoint
+	 * @param txObject the object passed to the joinpoint, defined by the subclass
+	 * @return the result of the target method execution
+	 * @throws Throwable exceptions are rethrown via the Rethrower class
+	 */
+	@SuppressAjWarnings("adviceDidNotMatch")
+	@Around(value = "transactionalMethodExecution(txObject)", argNames = "joinPoint,txObject")
+	public Object around(final ProceedingJoinPoint joinPoint, final Object txObject) throws Throwable {
+		MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); try {
+			// Proceed with the method execution
+			return invokeWithinTransaction(methodSignature.getMethod(), txObject.getClass(), joinPoint::proceed);
+		}
+		catch (RuntimeException | Error ex) {
+			throw ex;  // Rethrow runtime exceptions or errors
+		}
+		catch (Throwable thr) {
+			Rethrower.rethrow(thr);  // Rethrow checked exceptions as runtime exceptions
+			throw new IllegalStateException("Should never get here", thr);
+		}
+	}
+
+	/**
+	 * Matches the execution of any public method in a type with the Transactional
+	 * annotation, or any subtype of a type with the Transactional annotation.
+	 */
+	@Pointcut("execution(public * ((@org.springframework.transaction.annotation.Transactional *)+).*(..)) && within(@org.springframework.transaction.annotation.Transactional *)")
+	private void executionOfAnyPublicMethodInAtTransactionalType() {
+	}
+
+	/**
+	 * Matches the execution of any method with the Transactional annotation.
+	 */
+	@Pointcut("execution(@org.springframework.transaction.annotation.Transactional * *(..))")
+	private void executionOfTransactionalMethod() {
+	}
+
+	/**
+	 * Definition of pointcut from super aspect - matched join points
+	 * will have Spring transaction management applied.
+	 */
+	@Pointcut(value = "(executionOfAnyPublicMethodInAtTransactionalType() || executionOfTransactionalMethod()) && this(txObject)", argNames = "txObject")
+	public void transactionalMethodExecution(Object txObject) {
+	}
+
+	/**
+	 * Helper class to rethrow checked exceptions as runtime exceptions (workaround
+	 * for AspectJ's restriction on checked exceptions in around advice).
+	 */
+	private static class Rethrower {
+		public static void rethrow(final Throwable exception) {
+			class CheckedExceptionRethrower When using this aspect, you must annotate the implementation class
- * (and/or methods within that class), not the interface (if any) that
- * the class implements. AspectJ follows Java's rule that annotations on
- * interfaces are not inherited.
- *
- *  An @Transactional annotation on a class specifies the default transaction
- * semantics for the execution of any public operation in the class.
- *
- *  An @Transactional annotation on a method within the class overrides the
- * default transaction semantics given by the class annotation (if present).
- * Any method may be annotated (regardless of visibility). Annotating
- * non-public methods directly is the only way to get transaction demarcation
- * for the execution of such operations.
- *
- * @author Stephane Nicoll
- * @since 4.2
- * @see jakarta.transaction.Transactional
- * @see AnnotationTransactionAspect
- */
-@RequiredTypes("jakarta.transaction.Transactional")
-public aspect JtaAnnotationTransactionAspect extends AbstractTransactionAspect {
-
-	public JtaAnnotationTransactionAspect() {
-		super(new AnnotationTransactionAttributeSource(false));
-	}
-
-	/**
-	 * Matches the execution of any public method in a type with the Transactional
-	 * annotation, or any subtype of a type with the Transactional annotation.
-	 */
-	private pointcut executionOfAnyPublicMethodInAtTransactionalType() :
-		execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *);
-
-	/**
-	 * Matches the execution of any method with the Transactional annotation.
-	 */
-	private pointcut executionOfTransactionalMethod() :
-		execution(@Transactional * *(..));
-
-	/**
-	 * Definition of pointcut from super aspect - matched join points
-	 * will have Spring transaction management applied.
-	 */
-	protected pointcut transactionalMethodExecution(Object txObject) :
-		(executionOfAnyPublicMethodInAtTransactionalType() || executionOfTransactionalMethod() ) && this(txObject);
-
-}
diff --git a/spring-aspects/src/main/java/org/springframework/transaction/aspectj/JtaAnnotationTransactionAspect.java b/spring-aspects/src/main/java/org/springframework/transaction/aspectj/JtaAnnotationTransactionAspect.java
new file mode 100644
index 000000000000..c695e1fca847
--- /dev/null
+++ b/spring-aspects/src/main/java/org/springframework/transaction/aspectj/JtaAnnotationTransactionAspect.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2002-2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.transaction.aspectj;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.annotation.RequiredTypes;
+import org.aspectj.lang.annotation.SuppressAjWarnings;
+import org.aspectj.lang.reflect.MethodSignature;
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+
+/**
+ * Concrete AspectJ transaction aspect using the JTA 1.2
+ * {@link jakarta.transaction.Transactional} annotation.
+ *
+ *  When using this aspect, you must annotate the implementation class
+ * (and/or methods within that class), not the interface (if any) that
+ * the class implements. AspectJ follows Java's rule that annotations on
+ * interfaces are not inherited.
+ *
+ *  An @Transactional annotation on a class specifies the default transaction
+ * semantics for the execution of any public operation in the class.
+ *
+ *  An @Transactional annotation on a method within the class overrides the
+ * default transaction semantics given by the class annotation (if present).
+ * Any method may be annotated (regardless of visibility). Annotating
+ * non-public methods directly is the only way to get transaction demarcation
+ * for the execution of such operations.
+ *
+ * @author Stephane Nicoll
+ * @author Joshua Chen
+ * @since 4.2
+ * @see jakarta.transaction.Transactional
+ * @see AnnotationTransactionAspect
+ */
+@Aspect
+@RequiredTypes("jakarta.transaction.Transactional")
+public class JtaAnnotationTransactionAspect extends TransactionAspectSupport implements DisposableBean {
+
+	/**
+	 * Construct the aspect using the default transaction metadata retrieval strategy.
+	 */
+	public JtaAnnotationTransactionAspect() {
+		new AnnotationTransactionAttributeSource(false);  // Use AnnotationTransactionAttributeSource
+	}
+
+	@Override
+	public void destroy() {
+		// An aspect is basically a singleton -> cleanup on destruction
+		clearTransactionManagerCache();
+	}
+
+	/**
+	 * Around advice: intercepts transactional method execution.
+	 * @param joinPoint proceedingJoinPoint context for the joinpoint
+	 * @param txObject the object passed to the joinpoint, defined by the subclass
+	 * @return the result of the target method execution
+	 * @throws Throwable exceptions are rethrown via the Rethrower class
+	 */
+	@SuppressAjWarnings("adviceDidNotMatch")
+	@Around(value = "transactionalMethodExecution(txObject)", argNames = "joinPoint,txObject")
+	public Object around(final ProceedingJoinPoint joinPoint, final Object txObject) throws Throwable {
+		MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); try {
+			// Proceed with the method execution
+			return invokeWithinTransaction(methodSignature.getMethod(), txObject.getClass(), joinPoint::proceed);
+		}
+		catch (RuntimeException | Error ex) {
+			throw ex;  // Rethrow runtime exceptions or errors
+		}
+		catch (Throwable thr) {
+			JtaAnnotationTransactionAspect.Rethrower.rethrow(thr);  // Rethrow checked exceptions as runtime exceptions
+			throw new IllegalStateException("Should never get here", thr);
+		}
+	}
+
+	/**
+	 * Matches the execution of any public method in a type with the Transactional
+	 * annotation, or any subtype of a type with the Transactional annotation.
+	 */
+	@Pointcut("execution(public * ((@jakarta.transaction.Transactional *)+).*(..)) && within(@jakarta.transaction.Transactional *)")
+	private void executionOfAnyPublicMethodInAtTransactionalType() {
+	}
+
+	/**
+	 * Matches the execution of any method with the Transactional annotation.
+	 */
+	@Pointcut("execution(@jakarta.transaction.Transactional * *(..))")
+	private void executionOfTransactionalMethod() {
+	}
+
+	/**
+	 * Definition of pointcut from super aspect - matched join points
+	 * will have Spring transaction management applied.
+	 */
+	@Pointcut(value = "(executionOfAnyPublicMethodInAtTransactionalType() || executionOfTransactionalMethod()) && this(txObject)", argNames = "txObject")
+	public void transactionalMethodExecution(Object txObject) {
+	}
+
+	/**
+	 * Helper class to rethrow checked exceptions as runtime exceptions (workaround
+	 * for AspectJ's restriction on checked exceptions in around advice).
+	 */
+	private static class Rethrower {
+		public static void rethrow(final Throwable exception) {
+			class CheckedExceptionRethrower