diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 50430f75712..32ac333e0b0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 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. @@ -835,11 +835,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac /** * This implementation attempts to query the FactoryBean's generic parameter metadata * if present to determine the object type. If not present, i.e. the FactoryBean is - * declared as a raw type, checks the FactoryBean's {@code getObjectType} method + * declared as a raw type, it checks the FactoryBean's {@code getObjectType} method * on a plain instance of the FactoryBean, without bean properties applied yet. - * If this doesn't return a type yet, and {@code allowInit} is {@code true} a - * full creation of the FactoryBean is used as fallback (through delegation to the - * superclass's implementation). + * If this doesn't return a type yet and {@code allowInit} is {@code true}, full + * creation of the FactoryBean is attempted as fallback (through delegation to the + * superclass implementation). *

The shortcut check for a FactoryBean is only applied in case of a singleton * FactoryBean. If the FactoryBean instance itself is not kept as singleton, * it will be fully created to check the type of its exposed object. diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 61747b4fb24..43c4c624fad 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -1695,7 +1695,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp * already. The implementation is allowed to instantiate the target factory bean if * {@code allowInit} is {@code true} and the type cannot be determined another way; * otherwise it is restricted to introspecting signatures and related metadata. - *

If no {@link FactoryBean#OBJECT_TYPE_ATTRIBUTE} if set on the bean definition + *

If no {@link FactoryBean#OBJECT_TYPE_ATTRIBUTE} is set on the bean definition * and {@code allowInit} is {@code true}, the default implementation will create * the FactoryBean via {@code getBean} to call its {@code getObjectType} method. * Subclasses are encouraged to optimize this, typically by inspecting the generic diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationWithFactoryBeanBeanEarlyDeductionTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationWithFactoryBeanEarlyDeductionTests.java similarity index 70% rename from spring-context/src/test/java/org/springframework/context/annotation/ConfigurationWithFactoryBeanBeanEarlyDeductionTests.java rename to spring-context/src/test/java/org/springframework/context/annotation/ConfigurationWithFactoryBeanEarlyDeductionTests.java index 833e357f006..1290c38a086 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationWithFactoryBeanBeanEarlyDeductionTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationWithFactoryBeanEarlyDeductionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2024 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. @@ -29,7 +29,9 @@ import org.springframework.beans.factory.support.AbstractBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.GenericBeanDefinition; +import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.ResolvableType; import org.springframework.core.type.AnnotationMetadata; import static org.assertj.core.api.Assertions.assertThat; @@ -39,51 +41,62 @@ import static org.assertj.core.api.Assertions.assertThat; * {@link FactoryBean FactoryBeans} defined in the configuration. * * @author Phillip Webb + * @author Juergen Hoeller */ -public class ConfigurationWithFactoryBeanBeanEarlyDeductionTests { +class ConfigurationWithFactoryBeanEarlyDeductionTests { @Test - public void preFreezeDirect() { + void preFreezeDirect() { assertPreFreeze(DirectConfiguration.class); } @Test - public void postFreezeDirect() { + void postFreezeDirect() { assertPostFreeze(DirectConfiguration.class); } @Test - public void preFreezeGenericMethod() { + void preFreezeGenericMethod() { assertPreFreeze(GenericMethodConfiguration.class); } @Test - public void postFreezeGenericMethod() { + void postFreezeGenericMethod() { assertPostFreeze(GenericMethodConfiguration.class); } @Test - public void preFreezeGenericClass() { + void preFreezeGenericClass() { assertPreFreeze(GenericClassConfiguration.class); } @Test - public void postFreezeGenericClass() { + void postFreezeGenericClass() { assertPostFreeze(GenericClassConfiguration.class); } @Test - public void preFreezeAttribute() { + void preFreezeAttribute() { assertPreFreeze(AttributeClassConfiguration.class); } @Test - public void postFreezeAttribute() { + void postFreezeAttribute() { assertPostFreeze(AttributeClassConfiguration.class); } @Test - public void preFreezeUnresolvedGenericFactoryBean() { + void preFreezeTargetType() { + assertPreFreeze(TargetTypeConfiguration.class); + } + + @Test + void postFreezeTargetType() { + assertPostFreeze(TargetTypeConfiguration.class); + } + + @Test + void preFreezeUnresolvedGenericFactoryBean() { // Covers the case where a @Configuration is picked up via component scanning // and its bean definition only has a String bean class. In such cases // beanDefinition.hasBeanClass() returns false so we need to actually @@ -108,14 +121,13 @@ public class ConfigurationWithFactoryBeanBeanEarlyDeductionTests { } } + private void assertPostFreeze(Class configurationClass) { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - configurationClass); + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(configurationClass); assertContainsMyBeanName(context); } - private void assertPreFreeze(Class configurationClass, - BeanFactoryPostProcessor... postProcessors) { + private void assertPreFreeze(Class configurationClass, BeanFactoryPostProcessor... postProcessors) { NameCollectingBeanFactoryPostProcessor postProcessor = new NameCollectingBeanFactoryPostProcessor(); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); try { @@ -138,41 +150,38 @@ public class ConfigurationWithFactoryBeanBeanEarlyDeductionTests { assertThat(names).containsExactly("myBean"); } - private static class NameCollectingBeanFactoryPostProcessor - implements BeanFactoryPostProcessor { + + private static class NameCollectingBeanFactoryPostProcessor implements BeanFactoryPostProcessor { private String[] names; @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) - throws BeansException { - this.names = beanFactory.getBeanNamesForType(MyBean.class, true, false); + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + ResolvableType typeToMatch = ResolvableType.forClassWithGenerics(MyBean.class, String.class); + this.names = beanFactory.getBeanNamesForType(typeToMatch, true, false); } public String[] getNames() { return this.names; } - } @Configuration static class DirectConfiguration { @Bean - MyBean myBean() { - return new MyBean(); + MyBean myBean() { + return new MyBean<>(); } - } @Configuration static class GenericMethodConfiguration { @Bean - FactoryBean myBean() { - return new TestFactoryBean<>(new MyBean()); + FactoryBean> myBean() { + return new TestFactoryBean<>(new MyBean<>()); } - } @Configuration @@ -182,13 +191,11 @@ public class ConfigurationWithFactoryBeanBeanEarlyDeductionTests { MyFactoryBean myBean() { return new MyFactoryBean(); } - } @Configuration @Import(AttributeClassRegistrar.class) static class AttributeClassConfiguration { - } static class AttributeClassRegistrar implements ImportBeanDefinitionRegistrar { @@ -197,16 +204,34 @@ public class ConfigurationWithFactoryBeanBeanEarlyDeductionTests { public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { BeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition( RawWithAbstractObjectTypeFactoryBean.class).getBeanDefinition(); - definition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, MyBean.class); + definition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, + ResolvableType.forClassWithGenerics(MyBean.class, String.class)); registry.registerBeanDefinition("myBean", definition); } + } + @Configuration + @Import(TargetTypeRegistrar.class) + static class TargetTypeConfiguration { + } + + static class TargetTypeRegistrar implements ImportBeanDefinitionRegistrar { + + @Override + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { + RootBeanDefinition definition = new RootBeanDefinition(RawWithAbstractObjectTypeFactoryBean.class); + definition.setTargetType(ResolvableType.forClassWithGenerics(FactoryBean.class, + ResolvableType.forClassWithGenerics(MyBean.class, String.class))); + definition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, + ResolvableType.forClassWithGenerics(MyBean.class, String.class)); + registry.registerBeanDefinition("myBean", definition); + } } abstract static class AbstractMyBean { } - static class MyBean extends AbstractMyBean { + static class MyBean extends AbstractMyBean { } static class TestFactoryBean implements FactoryBean { @@ -218,7 +243,7 @@ public class ConfigurationWithFactoryBeanBeanEarlyDeductionTests { } @Override - public T getObject() throws Exception { + public T getObject() { return this.instance; } @@ -226,31 +251,26 @@ public class ConfigurationWithFactoryBeanBeanEarlyDeductionTests { public Class getObjectType() { return this.instance.getClass(); } - } - static class MyFactoryBean extends TestFactoryBean { + static class MyFactoryBean extends TestFactoryBean> { public MyFactoryBean() { - super(new MyBean()); + super(new MyBean<>()); } - } static class RawWithAbstractObjectTypeFactoryBean implements FactoryBean { - private final Object object = new MyBean(); - @Override public Object getObject() throws Exception { - return object; + throw new IllegalStateException(); } @Override public Class getObjectType() { return MyBean.class; } - } } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/rowset/ResultSetWrappingRowSetTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/rowset/ResultSetWrappingRowSetTests.java index 06ca4946598..8d946c13a90 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/rowset/ResultSetWrappingRowSetTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/rowset/ResultSetWrappingRowSetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2024 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. @@ -25,7 +25,6 @@ import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.jdbc.InvalidResultSetAccessException; @@ -38,174 +37,168 @@ import static org.mockito.Mockito.mock; /** * @author Thomas Risberg */ -public class ResultSetWrappingRowSetTests { +class ResultSetWrappingRowSetTests { - private ResultSet resultSet; + private final ResultSet resultSet = mock(ResultSet.class); - private ResultSetWrappingSqlRowSet rowSet; - - - @BeforeEach - public void setup() throws Exception { - resultSet = mock(ResultSet.class); - rowSet = new ResultSetWrappingSqlRowSet(resultSet); - } + private final ResultSetWrappingSqlRowSet rowSet = new ResultSetWrappingSqlRowSet(resultSet); @Test - public void testGetBigDecimalInt() throws Exception { + void testGetBigDecimalInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBigDecimal", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBigDecimal", int.class); doTest(rset, rowset, 1, BigDecimal.ONE); } @Test - public void testGetBigDecimalString() throws Exception { + void testGetBigDecimalString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBigDecimal", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBigDecimal", String.class); doTest(rset, rowset, "test", BigDecimal.ONE); } @Test - public void testGetStringInt() throws Exception { + void testGetStringInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getString", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getString", int.class); doTest(rset, rowset, 1, "test"); } @Test - public void testGetStringString() throws Exception { + void testGetStringString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getString", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getString", String.class); doTest(rset, rowset, "test", "test"); } @Test - public void testGetTimestampInt() throws Exception { + void testGetTimestampInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getTimestamp", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getTimestamp", int.class); doTest(rset, rowset, 1, new Timestamp(1234L)); } @Test - public void testGetTimestampString() throws Exception { + void testGetTimestampString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getTimestamp", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getTimestamp", String.class); doTest(rset, rowset, "test", new Timestamp(1234L)); } @Test - public void testGetDateInt() throws Exception { + void testGetDateInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getDate", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getDate", int.class); doTest(rset, rowset, 1, new Date(1234L)); } @Test - public void testGetDateString() throws Exception { + void testGetDateString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getDate", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getDate", String.class); doTest(rset, rowset, "test", new Date(1234L)); } @Test - public void testGetTimeInt() throws Exception { + void testGetTimeInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getTime", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getTime", int.class); doTest(rset, rowset, 1, new Time(1234L)); } @Test - public void testGetTimeString() throws Exception { + void testGetTimeString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getTime", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getTime", String.class); doTest(rset, rowset, "test", new Time(1234L)); } @Test - public void testGetObjectInt() throws Exception { + void testGetObjectInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getObject", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getObject", int.class); doTest(rset, rowset, 1, new Object()); } @Test - public void testGetObjectString() throws Exception { + void testGetObjectString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getObject", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getObject", String.class); doTest(rset, rowset, "test", new Object()); } @Test - public void testGetIntInt() throws Exception { + void testGetIntInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getInt", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getInt", int.class); doTest(rset, rowset, 1, 1); } @Test - public void testGetIntString() throws Exception { + void testGetIntString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getInt", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getInt", String.class); doTest(rset, rowset, "test", 1); } @Test - public void testGetFloatInt() throws Exception { + void testGetFloatInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getFloat", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getFloat", int.class); doTest(rset, rowset, 1, 1.0f); } @Test - public void testGetFloatString() throws Exception { + void testGetFloatString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getFloat", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getFloat", String.class); doTest(rset, rowset, "test", 1.0f); } @Test - public void testGetDoubleInt() throws Exception { + void testGetDoubleInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getDouble", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getDouble", int.class); doTest(rset, rowset, 1, 1.0d); } @Test - public void testGetDoubleString() throws Exception { + void testGetDoubleString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getDouble", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getDouble", String.class); doTest(rset, rowset, "test", 1.0d); } @Test - public void testGetLongInt() throws Exception { + void testGetLongInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getLong", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getLong", int.class); doTest(rset, rowset, 1, 1L); } @Test - public void testGetLongString() throws Exception { + void testGetLongString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getLong", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getLong", String.class); doTest(rset, rowset, "test", 1L); } @Test - public void testGetBooleanInt() throws Exception { + void testGetBooleanInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBoolean", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBoolean", int.class); doTest(rset, rowset, 1, true); } @Test - public void testGetBooleanString() throws Exception { + void testGetBooleanString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBoolean", int.class); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBoolean", String.class); doTest(rset, rowset, "test", true); } + private void doTest(Method rsetMethod, Method rowsetMethod, Object arg, Object ret) throws Exception { if (arg instanceof String) { given(resultSet.findColumn((String) arg)).willReturn(1); @@ -215,9 +208,9 @@ public class ResultSetWrappingRowSetTests { given(rsetMethod.invoke(resultSet, arg)).willReturn(ret).willThrow(new SQLException("test")); } rowsetMethod.invoke(rowSet, arg); - assertThatExceptionOfType(InvocationTargetException.class).isThrownBy(() -> - rowsetMethod.invoke(rowSet, arg)). - satisfies(ex -> assertThat(ex.getTargetException()).isExactlyInstanceOf(InvalidResultSetAccessException.class)); + assertThatExceptionOfType(InvocationTargetException.class) + .isThrownBy(() -> rowsetMethod.invoke(rowSet, arg)) + .satisfies(ex -> assertThat(ex.getTargetException()).isExactlyInstanceOf(InvalidResultSetAccessException.class)); } } diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java index ab3df073c7c..76e72bcd9d0 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2024 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. @@ -51,7 +51,7 @@ public class DefaultTransactionAttribute extends DefaultTransactionDefinition im /** - * Create a new DefaultTransactionAttribute, with default settings. + * Create a new {@code DefaultTransactionAttribute} with default settings. * Can be modified through bean property setters. * @see #setPropagationBehavior * @see #setIsolationLevel @@ -76,7 +76,7 @@ public class DefaultTransactionAttribute extends DefaultTransactionDefinition im } /** - * Create a new DefaultTransactionAttribute with the given + * Create a new {@code DefaultTransactionAttribute} with the given * propagation behavior. Can be modified through bean property setters. * @param propagationBehavior one of the propagation constants in the * TransactionDefinition interface diff --git a/spring-tx/src/main/java/org/springframework/transaction/reactive/AbstractReactiveTransactionManager.java b/spring-tx/src/main/java/org/springframework/transaction/reactive/AbstractReactiveTransactionManager.java index ba85becf0dc..2aaa2618079 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/reactive/AbstractReactiveTransactionManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/reactive/AbstractReactiveTransactionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 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. @@ -210,11 +210,13 @@ public abstract class AbstractReactiveTransactionManager implements ReactiveTran prepareSynchronization(synchronizationManager, status, definition)).thenReturn(status); } - // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED. + // PROPAGATION_REQUIRED, PROPAGATION_SUPPORTS, PROPAGATION_MANDATORY: + // regular participation in existing transaction. if (debugEnabled) { logger.debug("Participating in existing transaction"); } - return Mono.just(prepareReactiveTransaction(synchronizationManager, definition, transaction, false, debugEnabled, null)); + return Mono.just(prepareReactiveTransaction( + synchronizationManager, definition, transaction, false, debugEnabled, null)); } /** @@ -330,7 +332,7 @@ public abstract class AbstractReactiveTransactionManager implements ReactiveTran if (resourcesHolder != null) { Object suspendedResources = resourcesHolder.suspendedResources; if (suspendedResources != null) { - resume = doResume(synchronizationManager, transaction, suspendedResources); + resume = doResume(synchronizationManager, transaction, suspendedResources); } List suspendedSynchronizations = resourcesHolder.suspendedSynchronizations; if (suspendedSynchronizations != null) { diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java index e3f52fded7a..c27c4bd2fd6 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2024 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. @@ -451,7 +451,7 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran if (useSavepointForNestedTransaction()) { // Create savepoint within existing Spring-managed transaction, // through the SavepointManager API implemented by TransactionStatus. - // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization. + // Usually uses JDBC savepoints. Never activates Spring synchronization. DefaultTransactionStatus status = prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null); status.createAndHoldSavepoint(); @@ -465,7 +465,8 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran } } - // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED. + // PROPAGATION_REQUIRED, PROPAGATION_SUPPORTS, PROPAGATION_MANDATORY: + // regular participation in existing transaction. if (debugEnabled) { logger.debug("Participating in existing transaction"); } diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java b/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java index c42a0f8208e..8cce62d4237 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2024 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. @@ -65,7 +65,7 @@ public class DefaultTransactionDefinition implements TransactionDefinition, Seri /** - * Create a new DefaultTransactionDefinition, with default settings. + * Create a new {@code DefaultTransactionDefinition} with default settings. * Can be modified through bean property setters. * @see #setPropagationBehavior * @see #setIsolationLevel @@ -93,7 +93,7 @@ public class DefaultTransactionDefinition implements TransactionDefinition, Seri } /** - * Create a new DefaultTransactionDefinition with the given + * Create a new {@code DefaultTransactionDefinition} with the given * propagation behavior. Can be modified through bean property setters. * @param propagationBehavior one of the propagation constants in the * TransactionDefinition interface