Fix JDK 9+ generics compilation problem in TransactionAspectSupport

Includes consistent mentioning of ReactiveTransactionManager in javadoc.

Closes gh-22923
This commit is contained in:
Juergen Hoeller 2019-05-08 14:01:12 +02:00
parent dc01917dae
commit eb16e853b1
2 changed files with 49 additions and 52 deletions

View File

@ -57,13 +57,14 @@ import org.springframework.util.StringUtils;
* *
* <p>Subclasses are responsible for calling methods in this class in the correct order. * <p>Subclasses are responsible for calling methods in this class in the correct order.
* *
* <p>If no transaction name has been specified in the {@code TransactionAttribute}, * <p>If no transaction name has been specified in the {@link TransactionAttribute},
* the exposed name will be the {@code fully-qualified class name + "." + method name} * the exposed name will be the {@code fully-qualified class name + "." + method name}
* (by default). * (by default).
* *
* <p>Uses the <b>Strategy</b> design pattern. A {@code PlatformTransactionManager} * <p>Uses the <b>Strategy</b> design pattern. A {@link PlatformTransactionManager} or
* implementation will perform the actual transaction management, and a * {@link ReactiveTransactionManager} implementation will perform the actual transaction
* {@code TransactionAttributeSource} is used for determining transaction definitions. * management, and a {@link TransactionAttributeSource} (e.g. annotation-based) is used
* for determining transaction definitions for a particular class or method.
* *
* <p>A transaction aspect is serializable if its {@code PlatformTransactionManager} * <p>A transaction aspect is serializable if its {@code PlatformTransactionManager}
* and {@code TransactionAttributeSource} are serializable. * and {@code TransactionAttributeSource} are serializable.
@ -72,7 +73,10 @@ import org.springframework.util.StringUtils;
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Stéphane Nicoll * @author Stéphane Nicoll
* @author Sam Brannen * @author Sam Brannen
* @author Mark Paluch
* @since 1.1 * @since 1.1
* @see PlatformTransactionManager
* @see ReactiveTransactionManager
* @see #setTransactionManager * @see #setTransactionManager
* @see #setTransactionAttributes * @see #setTransactionAttributes
* @see #setTransactionAttributeSource * @see #setTransactionAttributeSource
@ -450,7 +454,8 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
else { else {
PlatformTransactionManager defaultTransactionManager = asPlatformTransactionManager(getTransactionManager()); PlatformTransactionManager defaultTransactionManager = asPlatformTransactionManager(getTransactionManager());
if (defaultTransactionManager == null) { if (defaultTransactionManager == null) {
defaultTransactionManager = asPlatformTransactionManager(this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY)); defaultTransactionManager = asPlatformTransactionManager(
this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY));
if (defaultTransactionManager == null) { if (defaultTransactionManager == null) {
defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class); defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
this.transactionManagerCache.putIfAbsent( this.transactionManagerCache.putIfAbsent(
@ -817,7 +822,6 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
this.adapter = adapter; this.adapter = adapter;
} }
@SuppressWarnings({ "unchecked", "rawtypes" })
public Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, InvocationCallback invocation) { public Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, InvocationCallback invocation) {
// If the transaction attribute is null, the method is non-transactional. // If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource(); TransactionAttributeSource tas = getTransactionAttributeSource();
@ -827,62 +831,53 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
// Optimize for Mono // Optimize for Mono
if (Mono.class.isAssignableFrom(method.getReturnType())) { if (Mono.class.isAssignableFrom(method.getReturnType())) {
return TransactionContextManager.currentContext().flatMap(context -> { return TransactionContextManager.currentContext().flatMap(context ->
// Standard transaction demarcation with getTransaction and commit/rollback calls. createTransactionIfNecessary(tm, txAttr, joinpointIdentification).flatMap(it -> {
Mono<ReactiveTransactionInfo> txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
return txInfo.flatMap(it -> {
try { try {
// This is an around advice: Invoke the next interceptor in the chain. // This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked. // This will normally result in a target object being invoked.
// Need re-wrapping of ReactiveTransaction until we get hold of the exception // Need re-wrapping of ReactiveTransaction until we get hold of the exception
// through usingWhen. // through usingWhen.
return Mono.<Object, ReactiveTransactionInfo>usingWhen(Mono.just(it), s -> { return Mono.<Object, ReactiveTransactionInfo>usingWhen(Mono.just(it), txInfo -> {
try { try {
return (Mono) invocation.proceedWithInvocation(); return (Mono<?>) invocation.proceedWithInvocation();
} }
catch (Throwable throwable) { catch (Throwable throwable) {
return Mono.error(throwable); return Mono.error(throwable);
} }
}, this::commitTransactionAfterReturning, s -> Mono.empty()) }, this::commitTransactionAfterReturning, txInfo -> Mono.empty())
.onErrorResume(ex -> completeTransactionAfterThrowing(it, ex) .onErrorResume(ex -> completeTransactionAfterThrowing(it, ex).then(Mono.error(ex)));
.then(Mono.error(ex)));
} }
catch (Throwable ex) { catch (Throwable ex) {
// target invocation exception // target invocation exception
return completeTransactionAfterThrowing(it, ex).then(Mono.error(ex)); return completeTransactionAfterThrowing(it, ex).then(Mono.error(ex));
} }
}); })).subscriberContext(TransactionContextManager.getOrCreateContext())
}).subscriberContext(TransactionContextManager.getOrCreateContext())
.subscriberContext(TransactionContextManager.getOrCreateContextHolder()); .subscriberContext(TransactionContextManager.getOrCreateContextHolder());
} }
return TransactionContextManager.currentContext().flatMapMany(context -> { return TransactionContextManager.currentContext().flatMapMany(context ->
// Standard transaction demarcation with getTransaction and commit/rollback calls. createTransactionIfNecessary(tm, txAttr, joinpointIdentification).flatMapMany(it -> {
Mono<ReactiveTransactionInfo> txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
return txInfo.flatMapMany(it -> {
try { try {
// This is an around advice: Invoke the next interceptor in the chain. // This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked. // This will normally result in a target object being invoked.
// Need re-wrapping of ReactiveTransaction until we get hold of the exception // Need re-wrapping of ReactiveTransaction until we get hold of the exception
// through usingWhen. // through usingWhen.
return Flux.usingWhen(Mono.just(it), s -> { return Flux.usingWhen(Mono.just(it), txInfo -> {
try { try {
return this.adapter.toPublisher( return this.adapter.toPublisher(invocation.proceedWithInvocation());
invocation.proceedWithInvocation());
} }
catch (Throwable throwable) { catch (Throwable throwable) {
return Mono.error(throwable); return Mono.error(throwable);
} }
}, this::commitTransactionAfterReturning, s -> Mono.empty()) }, this::commitTransactionAfterReturning, txInfo -> Mono.empty())
.onErrorResume(ex -> completeTransactionAfterThrowing(it, ex) .onErrorResume(ex -> completeTransactionAfterThrowing(it, ex).then(Mono.error(ex)));
.then(Mono.error(ex)));
} }
catch (Throwable ex) { catch (Throwable ex) {
// target invocation exception // target invocation exception
return completeTransactionAfterThrowing(it, ex).then(Mono.error(ex)); return completeTransactionAfterThrowing(it, ex).then(Mono.error(ex));
} }
}); })).subscriberContext(TransactionContextManager.getOrCreateContext())
}).subscriberContext(TransactionContextManager.getOrCreateContext())
.subscriberContext(TransactionContextManager.getOrCreateContextHolder()); .subscriberContext(TransactionContextManager.getOrCreateContextHolder());
} }
@ -903,7 +898,8 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
else { else {
ReactiveTransactionManager defaultTransactionManager = asReactiveTransactionManager(getTransactionManager()); ReactiveTransactionManager defaultTransactionManager = asReactiveTransactionManager(getTransactionManager());
if (defaultTransactionManager == null) { if (defaultTransactionManager == null) {
defaultTransactionManager = asReactiveTransactionManager(transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY)); defaultTransactionManager = asReactiveTransactionManager(
transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY));
if (defaultTransactionManager == null) { if (defaultTransactionManager == null) {
defaultTransactionManager = beanFactory.getBean(ReactiveTransactionManager.class); defaultTransactionManager = beanFactory.getBean(ReactiveTransactionManager.class);
transactionManagerCache.putIfAbsent( transactionManagerCache.putIfAbsent(
@ -963,8 +959,8 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
} }
} }
return tx.map(it -> prepareTransactionInfo(tm, attrToUse, joinpointIdentification, it)) return tx.map(it -> prepareTransactionInfo(tm, attrToUse, joinpointIdentification, it)).switchIfEmpty(
.switchIfEmpty(Mono.defer(() -> Mono.just(prepareTransactionInfo(tm, attrToUse, joinpointIdentification, null)))); Mono.defer(() -> Mono.just(prepareTransactionInfo(tm, attrToUse, joinpointIdentification, null))));
} }
private ReactiveTransactionInfo prepareTransactionInfo(@Nullable ReactiveTransactionManager tm, private ReactiveTransactionInfo prepareTransactionInfo(@Nullable ReactiveTransactionManager tm,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,7 +33,8 @@ import org.springframework.transaction.PlatformTransactionManager;
/** /**
* AOP Alliance MethodInterceptor for declarative transaction * AOP Alliance MethodInterceptor for declarative transaction
* management using the common Spring transaction infrastructure * management using the common Spring transaction infrastructure
* ({@link org.springframework.transaction.PlatformTransactionManager}). * ({@link org.springframework.transaction.PlatformTransactionManager}/
* {@link org.springframework.transaction.ReactiveTransactionManager}).
* *
* <p>Derives from the {@link TransactionAspectSupport} class which * <p>Derives from the {@link TransactionAspectSupport} class which
* contains the integration with Spring's underlying transaction API. * contains the integration with Spring's underlying transaction API.