Merge branch '6.0.x'

# Conflicts:
#	spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
This commit is contained in:
Juergen Hoeller
2023-06-02 23:30:04 +02:00
33 changed files with 176 additions and 167 deletions

View File

@@ -302,7 +302,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
}
private void bindParameterName(int index, String name) {
private void bindParameterName(int index, @Nullable String name) {
this.parameterNameBindings[index] = name;
this.numberOfRemainingUnboundArguments--;
}

View File

@@ -34,6 +34,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Convenient superclass for
@@ -82,6 +83,11 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
return this.beanFactory;
}
private ConfigurableBeanFactory getConfigurableBeanFactory() {
Assert.state(this.beanFactory != null, "BeanFactory not set");
return this.beanFactory;
}
//---------------------------------------------------------------------
// Implementation of the TargetSourceCreator interface
@@ -105,7 +111,7 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
// We need to override just this bean definition, as it may reference other beans
// and we're happy to take the parent's definition for those.
// Always use prototype scope if demanded.
BeanDefinition bd = this.beanFactory.getMergedBeanDefinition(beanName);
BeanDefinition bd = getConfigurableBeanFactory().getMergedBeanDefinition(beanName);
GenericBeanDefinition bdCopy = new GenericBeanDefinition(bd);
if (isPrototypeBased()) {
bdCopy.setScope(BeanDefinition.SCOPE_PROTOTYPE);
@@ -127,7 +133,7 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
protected DefaultListableBeanFactory getInternalBeanFactoryForBean(String beanName) {
synchronized (this.internalBeanFactories) {
return this.internalBeanFactories.computeIfAbsent(beanName,
name -> buildInternalBeanFactory(this.beanFactory));
name -> buildInternalBeanFactory(getConfigurableBeanFactory()));
}
}

View File

@@ -25,6 +25,7 @@ import org.springframework.aop.TargetSource;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
@@ -58,16 +59,18 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
protected final transient Log logger = LogFactory.getLog(getClass());
/** Name of the target bean we will create on each invocation. */
@Nullable
private String targetBeanName;
/** Class of the target. */
@Nullable
private volatile Class<?> targetClass;
/**
* BeanFactory that owns this TargetSource. We need to hold onto this
* reference so that we can create new prototype instances as necessary.
*/
@SuppressWarnings("serial")
@Nullable
private BeanFactory beanFactory;
@@ -88,6 +91,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
* Return the name of the target bean in the factory.
*/
public String getTargetBeanName() {
Assert.state(this.targetBeanName != null, "Target bean name not set");
return this.targetBeanName;
}
@@ -117,11 +121,13 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
* Return the owning BeanFactory.
*/
public BeanFactory getBeanFactory() {
Assert.state(this.beanFactory != null, "BeanFactory not set");
return this.beanFactory;
}
@Override
@Nullable
public Class<?> getTargetClass() {
Class<?> targetClass = this.targetClass;
if (targetClass != null) {
@@ -130,7 +136,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
synchronized (this) {
// Full check within synchronization, entering the BeanFactory interaction algorithm only once...
targetClass = this.targetClass;
if (targetClass == null && this.beanFactory != null) {
if (targetClass == null && this.beanFactory != null && this.targetBeanName != null) {
// Determine type of the target bean.
targetClass = this.beanFactory.getType(this.targetBeanName);
if (targetClass == null) {
@@ -184,18 +190,16 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
@Override
public int hashCode() {
int hashCode = getClass().hashCode();
hashCode = 13 * hashCode + ObjectUtils.nullSafeHashCode(this.beanFactory);
hashCode = 13 * hashCode + ObjectUtils.nullSafeHashCode(this.targetBeanName);
return hashCode;
return getClass().hashCode() * 13 + ObjectUtils.nullSafeHashCode(this.targetBeanName);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(getClass().getSimpleName());
sb.append(" for target bean '").append(this.targetBeanName).append('\'');
if (this.targetClass != null) {
sb.append(" of type [").append(this.targetClass.getName()).append(']');
Class<?> targetClass = this.targetClass;
if (targetClass != null) {
sb.append(" of type [").append(targetClass.getName()).append(']');
}
return sb.toString();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2023 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.
@@ -46,6 +46,7 @@ public abstract class AbstractLazyCreationTargetSource implements TargetSource {
protected final Log logger = LogFactory.getLog(getClass());
/** The lazily initialized target object. */
@Nullable
private Object lazyTarget;

View File

@@ -70,6 +70,7 @@ public final class EmptyTargetSource implements TargetSource, Serializable {
// Instance implementation
//---------------------------------------------------------------------
@Nullable
private final Class<?> targetClass;
private final boolean isStatic;

View File

@@ -97,12 +97,11 @@ public class HotSwappableTargetSource implements TargetSource, Serializable {
/**
* Two HotSwappableTargetSources are equal if the current target
* objects are equal.
* Two HotSwappableTargetSources are equal if the current target objects are equal.
*/
@Override
public boolean equals(@Nullable Object obj) {
return (this == obj || (obj instanceof HotSwappableTargetSource that &&
public boolean equals(@Nullable Object other) {
return (this == other || (other instanceof HotSwappableTargetSource that &&
this.target.equals(that.target)));
}

View File

@@ -84,13 +84,8 @@ public class SingletonTargetSource implements TargetSource, Serializable {
*/
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof SingletonTargetSource otherTargetSource)) {
return false;
}
return this.target.equals(otherTargetSource.target);
return (this == other || (other instanceof SingletonTargetSource that &&
this.target.equals(that.target)));
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2023 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.
@@ -58,7 +58,12 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
* is meant to be per thread per instance of the ThreadLocalTargetSource class.
*/
private final ThreadLocal<Object> targetInThread =
new NamedThreadLocal<>("Thread-local instance of bean '" + getTargetBeanName() + "'");
new NamedThreadLocal<>("Thread-local instance of bean") {
@Override
public String toString() {
return super.toString() + " '" + getTargetBeanName() + "'";
}
};
/**
* Set of managed targets, enabling us to keep track of the targets we've created.

View File

@@ -102,7 +102,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
private boolean singletonsCurrentlyInDestruction = false;
/** Disposable bean instances: bean name to disposable instance. */
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
private final Map<String, DisposableBean> disposableBeans = new LinkedHashMap<>();
/** Map between containing bean names: bean name to Set of bean names that the bean contains. */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
@@ -554,7 +554,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
// Destroy the corresponding DisposableBean instance.
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
disposableBean = this.disposableBeans.remove(beanName);
}
destroyBean(beanName, disposableBean);
}

View File

@@ -274,7 +274,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
handleAsyncError(ex);
}
else if (event != null) {
publishEvent(event);
publishEvents(event);
}
});
}
@@ -466,6 +466,9 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
}
/**
* Inner class to avoid a hard dependency on the Reactive Streams API at runtime.
*/
private class ReactiveResultHandler {
public boolean subscribeToPublisher(Object result) {
@@ -479,6 +482,9 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
}
/**
* Reactive Streams Subscriber for publishing follow-up events.
*/
private class EventPublicationSubscriber implements Subscriber<Object> {
@Override

View File

@@ -1049,7 +1049,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* @see #close()
* @see #registerShutdownHook()
*/
@SuppressWarnings("deprecation")
protected void doClose() {
// Check whether an actual close attempt is necessary...
if (this.active.get() && this.closed.compareAndSet(false, true)) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@@ -41,6 +41,7 @@ class ImportTests {
private DefaultListableBeanFactory processConfigurationClasses(Class<?>... classes) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.setAllowBeanDefinitionOverriding(false);
for (Class<?> clazz : classes) {
beanFactory.registerBeanDefinition(clazz.getSimpleName(), new RootBeanDefinition(clazz));
}
@@ -56,9 +57,10 @@ class ImportTests {
for (Class<?> clazz : classes) {
beanFactory.getBean(clazz);
}
}
// ------------------------------------------------------------------------
@Test
void testProcessImportsWithAsm() {
int configClasses = 2;
@@ -158,6 +160,13 @@ class ImportTests {
assertBeanDefinitionCount(configClasses + beansInClasses, FirstLevel.class);
}
@Test
void testImportAnnotationWithThreeLevelRecursionAndDoubleImport() {
int configClasses = 5;
int beansInClasses = 5;
assertBeanDefinitionCount(configClasses + beansInClasses, FirstLevel.class, FirstLevelPlus.class);
}
// ------------------------------------------------------------------------
@Test
@@ -167,7 +176,6 @@ class ImportTests {
assertBeanDefinitionCount((configClasses + beansInClasses), WithMultipleArgumentsToImportAnnotation.class);
}
@Test
void testImportAnnotationWithMultipleArgumentsResultingInOverriddenBeanDefinition() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
@@ -245,6 +253,11 @@ class ImportTests {
}
}
@Configuration
@Import(ThirdLevel.class)
static class FirstLevelPlus {
}
@Configuration
@Import({ThirdLevel.class, InitBean.class})
static class SecondLevel {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2023 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.
@@ -36,6 +36,12 @@ public class LogFactoryService extends LogFactory {
private final Map<String, Object> attributes = new ConcurrentHashMap<>();
public LogFactoryService() {
System.out.println("Standard Commons Logging discovery in action with spring-jcl: " +
"please remove commons-logging.jar from classpath in order to avoid potential conflicts");
}
@Override
public Log getInstance(Class<?> clazz) {
return getInstance(clazz.getName());

View File

@@ -75,7 +75,7 @@ public class ConnectionFactoryUtilsUnitTests {
@Test
public void shouldNotTranslateUnknownExceptions() {
Exception exception = ConnectionFactoryUtils.convertR2dbcException("", "",
new MyTransientExceptions());
new MyTransientException());
assertThat(exception).isExactlyInstanceOf(UncategorizedR2dbcException.class);
}
@@ -153,7 +153,7 @@ public class ConnectionFactoryUtilsUnitTests {
@SuppressWarnings("serial")
private static class MyTransientExceptions extends R2dbcException {
private static class MyTransientException extends R2dbcException {
}
}

View File

@@ -40,7 +40,7 @@ class DelegatingConnectionFactoryUnitTests {
@Test
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
void shouldDelegateGetConnection() {
Mono<Connection> connectionMono = Mono.just(connectionMock);
when(delegate.create()).thenReturn((Mono) connectionMono);
@@ -53,6 +53,7 @@ class DelegatingConnectionFactoryUnitTests {
assertThat(connectionFactory.unwrap()).isSameAs(delegate);
}
static class ExampleConnectionFactory extends DelegatingConnectionFactory {
ExampleConnectionFactory(ConnectionFactory targetConnectionFactory) {

View File

@@ -65,6 +65,7 @@ class R2dbcTransactionManagerUnitTests {
private R2dbcTransactionManager tm;
@BeforeEach
@SuppressWarnings({ "unchecked", "rawtypes" })
void before() {
@@ -74,6 +75,7 @@ class R2dbcTransactionManagerUnitTests {
tm = new R2dbcTransactionManager(connectionFactoryMock);
}
@Test
void testSimpleTransaction() {
TestTransactionSynchronization sync = new TestTransactionSynchronization(
@@ -445,8 +447,7 @@ class R2dbcTransactionManagerUnitTests {
}
private static class TestTransactionSynchronization
implements TransactionSynchronization {
private static class TestTransactionSynchronization implements TransactionSynchronization {
private int status;
@@ -519,7 +520,6 @@ class R2dbcTransactionManagerUnitTests {
this.afterCompletionCalled = true;
assertThat(status).isEqualTo(this.status);
}
}
}

View File

@@ -48,8 +48,8 @@ class SingleConnectionFactoryUnitTests {
Connection c1 = cf1.block();
Connection c2 = cf2.block();
assertThat(c1).isSameAs(c2);
factory.destroy();
}
@@ -63,7 +63,6 @@ class SingleConnectionFactoryUnitTests {
.verifyComplete();
factory.setAutoCommit(true);
factory.create().as(StepVerifier::create)
.consumeNextWith(actual -> assertThat(actual.isAutoCommit()).isTrue())
.verifyComplete();
@@ -75,7 +74,6 @@ class SingleConnectionFactoryUnitTests {
@SuppressWarnings("rawtypes")
void shouldSuppressClose() {
SingleConnectionFactory factory = new SingleConnectionFactory("r2dbc:h2:mem:///foo", true);
Connection connection = factory.create().block();
StepVerifier.create(connection.close()).verifyComplete();
@@ -85,19 +83,19 @@ class SingleConnectionFactoryUnitTests {
StepVerifier.create(
connection.setTransactionIsolationLevel(IsolationLevel.READ_COMMITTED))
.verifyComplete();
factory.destroy();
}
@Test
void shouldNotSuppressClose() {
SingleConnectionFactory factory = new SingleConnectionFactory("r2dbc:h2:mem:///foo", false);
Connection connection = factory.create().block();
StepVerifier.create(connection.close()).verifyComplete();
StepVerifier.create(connection.setTransactionIsolationLevel(IsolationLevel.READ_COMMITTED))
.verifyError(R2dbcNonTransientResourceException.class);
factory.destroy();
}
@@ -107,7 +105,6 @@ class SingleConnectionFactoryUnitTests {
ConnectionFactoryMetadata metadata = mock();
SingleConnectionFactory factory = new SingleConnectionFactory(connectionMock, metadata, true);
Connection connection = factory.create().block();
ConnectionFactoryUtils.releaseConnection(connection, factory)
@@ -125,7 +122,6 @@ class SingleConnectionFactoryUnitTests {
when(otherConnection.close()).thenReturn(Mono.empty());
SingleConnectionFactory factory = new SingleConnectionFactory(connectionMock, metadata, false);
factory.create().as(StepVerifier::create).expectNextCount(1).verifyComplete();
ConnectionFactoryUtils.releaseConnection(otherConnection, factory)

View File

@@ -55,6 +55,7 @@ class TransactionAwareConnectionFactoryProxyUnitTests {
R2dbcTransactionManager tm;
@BeforeEach
@SuppressWarnings({ "rawtypes", "unchecked" })
void before() {
@@ -63,6 +64,7 @@ class TransactionAwareConnectionFactoryProxyUnitTests {
tm = new R2dbcTransactionManager(connectionFactoryMock);
}
@Test
void createShouldWrapConnection() {
new TransactionAwareConnectionFactoryProxy(connectionFactoryMock).create()

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 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.
@@ -46,23 +46,15 @@ abstract class AbstractDatabasePopulatorTests {
databasePopulator.setIgnoreFailedDrops(true);
runPopulator();
assertUsersDatabaseCreated("Heisenberg");
}
private void runPopulator() {
databasePopulator.populate(getConnectionFactory()) //
.as(StepVerifier::create) //
.verifyComplete();
}
@Test
void scriptWithStandardEscapedLiteral() {
databasePopulator.addScript(defaultSchema());
databasePopulator.addScript(resource("db-test-data-escaped-literal.sql"));
runPopulator();
assertUsersDatabaseCreated("'Heisenberg'");
}
@@ -72,7 +64,6 @@ abstract class AbstractDatabasePopulatorTests {
databasePopulator.addScript(resource("db-test-data-mysql-escaped-literal.sql"));
runPopulator();
assertUsersDatabaseCreated("\\$Heisenberg\\$");
}
@@ -82,7 +73,6 @@ abstract class AbstractDatabasePopulatorTests {
databasePopulator.addScript(resource("db-test-data-multiple.sql"));
runPopulator();
assertUsersDatabaseCreated("Heisenberg", "Jesse");
}
@@ -93,10 +83,36 @@ abstract class AbstractDatabasePopulatorTests {
databasePopulator.setSeparator("@@");
runPopulator();
assertUsersDatabaseCreated("Heisenberg", "Jesse");
}
private void runPopulator() {
databasePopulator.populate(getConnectionFactory()) //
.as(StepVerifier::create) //
.verifyComplete();
}
void assertUsersDatabaseCreated(String... lastNames) {
assertUsersDatabaseCreated(getConnectionFactory(), lastNames);
}
void assertUsersDatabaseCreated(ConnectionFactory connectionFactory,String... lastNames) {
DatabaseClient client = DatabaseClient.create(connectionFactory);
for (String lastName : lastNames) {
client.sql("select count(0) from users where last_name = :name") //
.bind("name", lastName) //
.map((row, metadata) -> row.get(0)) //
.first() //
.map(number -> ((Number) number).intValue()) //
.as(StepVerifier::create) //
.expectNext(1).as("Did not find user with last name [" + lastName + "].") //
.verifyComplete();
}
}
abstract ConnectionFactory getConnectionFactory();
Resource resource(String path) {
@@ -111,25 +127,4 @@ abstract class AbstractDatabasePopulatorTests {
return resource("users-schema.sql");
}
void assertUsersDatabaseCreated(String... lastNames) {
assertUsersDatabaseCreated(getConnectionFactory(), lastNames);
}
void assertUsersDatabaseCreated(ConnectionFactory connectionFactory,
String... lastNames) {
DatabaseClient client = DatabaseClient.create(connectionFactory);
for (String lastName : lastNames) {
client.sql("select count(0) from users where last_name = :name") //
.bind("name", lastName) //
.map((row, metadata) -> row.get(0)) //
.first() //
.map(number -> ((Number) number).intValue()) //
.as(StepVerifier::create) //
.expectNext(1).as("Did not find user with last name [" + lastName + "].") //
.verifyComplete();
}
}
}

View File

@@ -52,6 +52,7 @@ class CompositeDatabasePopulatorTests {
when(mockedDatabasePopulator2.populate(mockedConnection)).thenReturn(Mono.empty());
}
@Test
void addPopulators() {
CompositeDatabasePopulator populator = new CompositeDatabasePopulator();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 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.
@@ -30,8 +30,8 @@ class H2DatabasePopulatorIntegrationTests extends AbstractDatabasePopulatorTests
UUID databaseName = UUID.randomUUID();
ConnectionFactory connectionFactory = ConnectionFactories.get("r2dbc:h2:mem:///"
+ databaseName + "?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
ConnectionFactory connectionFactory = ConnectionFactories.get(
"r2dbc:h2:mem:///" + databaseName + "?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@@ -43,7 +43,6 @@ import static org.springframework.r2dbc.connection.init.ScriptUtils.DEFAULT_STAT
* @author Nicolas Debeissat
* @author Mark Paluch
* @since 5.3
* @see ScriptUtilsIntegrationTests
*/
public class ScriptUtilsUnitTests {
@@ -133,8 +132,8 @@ public class ScriptUtilsUnitTests {
}
private void splitScriptContainingComments(String script, String... commentPrefixes) {
List<String> statements = ScriptUtils.splitSqlScript(null, script, ";", commentPrefixes, DEFAULT_BLOCK_COMMENT_START_DELIMITER,
DEFAULT_BLOCK_COMMENT_END_DELIMITER);
List<String> statements = ScriptUtils.splitSqlScript(null, script, ";", commentPrefixes,
DEFAULT_BLOCK_COMMENT_START_DELIMITER, DEFAULT_BLOCK_COMMENT_END_DELIMITER);
String statement1 = "insert into customer (id, name) values (1, 'Rod; Johnson'), (2, 'Adrian Collier')";
String statement2 = "insert into orders(id, order_date, customer_id) values (1, '2008-01-02', 2)";
@@ -218,20 +217,21 @@ public class ScriptUtilsUnitTests {
~/* double \\" quotes */\n insert into colors(color_num) values(42);~ | ; | true
""")
public void containsStatementSeparator(String script, String delimiter, boolean expected) {
boolean contains = ScriptUtils.containsStatementSeparator(null, script, delimiter, DEFAULT_COMMENT_PREFIXES,
DEFAULT_BLOCK_COMMENT_START_DELIMITER, DEFAULT_BLOCK_COMMENT_END_DELIMITER);
boolean contains = ScriptUtils.containsStatementSeparator(null, script, delimiter,
DEFAULT_COMMENT_PREFIXES, DEFAULT_BLOCK_COMMENT_START_DELIMITER, DEFAULT_BLOCK_COMMENT_END_DELIMITER);
assertThat(contains).isEqualTo(expected);
}
private String readScript(String path) throws Exception {
private String readScript(String path) {
EncodedResource resource = new EncodedResource(new ClassPathResource(path, getClass()));
return ScriptUtils.readScript(resource, DefaultDataBufferFactory.sharedInstance, DEFAULT_STATEMENT_SEPARATOR).block();
}
private static List<String> splitSqlScript(String script, String separator) throws ScriptException {
return ScriptUtils.splitSqlScript(null, script, separator, DEFAULT_COMMENT_PREFIXES, DEFAULT_BLOCK_COMMENT_START_DELIMITER,
DEFAULT_BLOCK_COMMENT_END_DELIMITER);
return ScriptUtils.splitSqlScript(null, script, separator, DEFAULT_COMMENT_PREFIXES,
DEFAULT_BLOCK_COMMENT_START_DELIMITER, DEFAULT_BLOCK_COMMENT_END_DELIMITER);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2023 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.
@@ -48,15 +48,16 @@ public class AbstractRoutingConnectionFactoryUnitTests {
DummyRoutingConnectionFactory connectionFactory;
@BeforeEach
public void before() {
connectionFactory = new DummyRoutingConnectionFactory();
connectionFactory.setDefaultTargetConnectionFactory(defaultConnectionFactory);
}
@Test
public void shouldDetermineRoutedFactory() {
connectionFactory.setTargetConnectionFactories(
singletonMap("key", routedConnectionFactory));
connectionFactory.setConnectionFactoryLookup(new MapConnectionFactoryLookup());
@@ -85,8 +86,8 @@ public class AbstractRoutingConnectionFactoryUnitTests {
public void initializationShouldFailUnsupportedLookupKey() {
connectionFactory.setTargetConnectionFactories(singletonMap("key", new Object()));
assertThatThrownBy(() -> connectionFactory.afterPropertiesSet()).isInstanceOf(
IllegalArgumentException.class);
assertThatThrownBy(() -> connectionFactory.afterPropertiesSet())
.isInstanceOf(IllegalArgumentException.class);
}
@Test
@@ -96,8 +97,7 @@ public class AbstractRoutingConnectionFactoryUnitTests {
assertThatThrownBy(() -> connectionFactory.afterPropertiesSet())
.isInstanceOf(ConnectionFactoryLookupFailureException.class)
.hasMessageContaining(
"No ConnectionFactory with name 'value' registered");
.hasMessageContaining("No ConnectionFactory with name 'value' registered");
}
@Test
@@ -144,12 +144,11 @@ public class AbstractRoutingConnectionFactoryUnitTests {
@Test
public void shouldLookupFromMap() {
MapConnectionFactoryLookup lookup = new MapConnectionFactoryLookup("lookup-key",
routedConnectionFactory);
MapConnectionFactoryLookup lookup =
new MapConnectionFactoryLookup("lookup-key", routedConnectionFactory);
connectionFactory.setConnectionFactoryLookup(lookup);
connectionFactory.setTargetConnectionFactories(
singletonMap("my-key", "lookup-key"));
connectionFactory.setTargetConnectionFactories(singletonMap("my-key", "lookup-key"));
connectionFactory.afterPropertiesSet();
connectionFactory.determineTargetConnectionFactory()
@@ -183,6 +182,7 @@ public class AbstractRoutingConnectionFactoryUnitTests {
.verifyComplete();
}
static class DummyRoutingConnectionFactory extends AbstractRoutingConnectionFactory {
@Override

View File

@@ -44,18 +44,17 @@ public class BeanFactoryConnectionFactoryLookupUnitTests {
@Mock
BeanFactory beanFactory;
@Test
public void shouldLookupConnectionFactory() {
DummyConnectionFactory expectedConnectionFactory = new DummyConnectionFactory();
when(beanFactory.getBean(CONNECTION_FACTORY_BEAN_NAME,
ConnectionFactory.class)).thenReturn(expectedConnectionFactory);
when(beanFactory.getBean(CONNECTION_FACTORY_BEAN_NAME, ConnectionFactory.class))
.thenReturn(expectedConnectionFactory);
BeanFactoryConnectionFactoryLookup lookup = new BeanFactoryConnectionFactoryLookup();
lookup.setBeanFactory(beanFactory);
ConnectionFactory connectionFactory = lookup.getConnectionFactory(
CONNECTION_FACTORY_BEAN_NAME);
ConnectionFactory connectionFactory = lookup.getConnectionFactory(CONNECTION_FACTORY_BEAN_NAME);
assertThat(connectionFactory).isNotNull();
assertThat(connectionFactory).isSameAs(expectedConnectionFactory);
}
@@ -63,26 +62,21 @@ public class BeanFactoryConnectionFactoryLookupUnitTests {
@Test
public void shouldLookupWhereBeanFactoryYieldsNonConnectionFactoryType() {
BeanFactory beanFactory = mock();
when(beanFactory.getBean(CONNECTION_FACTORY_BEAN_NAME, ConnectionFactory.class))
.thenThrow(new BeanNotOfRequiredTypeException(
CONNECTION_FACTORY_BEAN_NAME, ConnectionFactory.class, String.class));
when(beanFactory.getBean(CONNECTION_FACTORY_BEAN_NAME,
ConnectionFactory.class)).thenThrow(
new BeanNotOfRequiredTypeException(CONNECTION_FACTORY_BEAN_NAME,
ConnectionFactory.class, String.class));
BeanFactoryConnectionFactoryLookup lookup = new BeanFactoryConnectionFactoryLookup(
beanFactory);
assertThatExceptionOfType(
ConnectionFactoryLookupFailureException.class).isThrownBy(
() -> lookup.getConnectionFactory(CONNECTION_FACTORY_BEAN_NAME));
BeanFactoryConnectionFactoryLookup lookup = new BeanFactoryConnectionFactoryLookup(beanFactory);
assertThatExceptionOfType(ConnectionFactoryLookupFailureException.class)
.isThrownBy(() -> lookup.getConnectionFactory(CONNECTION_FACTORY_BEAN_NAME));
}
@Test
public void shouldLookupWhereBeanFactoryHasNotBeenSupplied() {
BeanFactoryConnectionFactoryLookup lookup = new BeanFactoryConnectionFactoryLookup();
assertThatThrownBy(() -> lookup.getConnectionFactory(
CONNECTION_FACTORY_BEAN_NAME)).isInstanceOf(IllegalStateException.class);
assertThatThrownBy(() -> lookup.getConnectionFactory(CONNECTION_FACTORY_BEAN_NAME))
.isInstanceOf(IllegalStateException.class);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2023 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.
@@ -23,8 +23,8 @@ import org.reactivestreams.Publisher;
/**
* Stub, do-nothing {@link ConnectionFactory} implementation.
* <p>
* All methods throw {@link UnsupportedOperationException}.
*
* <p>All methods throw {@link UnsupportedOperationException}.
*
* @author Mark Paluch
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2023 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.
@@ -40,23 +40,19 @@ public class MapConnectionFactoryLookupUnitTests {
Map<String, ConnectionFactory> connectionFactories = lookup.getConnectionFactories();
assertThatThrownBy(() -> connectionFactories.put("",
new DummyConnectionFactory())).isInstanceOf(
UnsupportedOperationException.class);
new DummyConnectionFactory())).isInstanceOf(UnsupportedOperationException.class);
}
@Test
public void shouldLookupConnectionFactory() {
Map<String, ConnectionFactory> connectionFactories = new HashMap<>();
DummyConnectionFactory expectedConnectionFactory = new DummyConnectionFactory();
connectionFactories.put(CONNECTION_FACTORY_NAME, expectedConnectionFactory);
MapConnectionFactoryLookup lookup = new MapConnectionFactoryLookup();
MapConnectionFactoryLookup lookup = new MapConnectionFactoryLookup();
lookup.setConnectionFactories(connectionFactories);
ConnectionFactory connectionFactory = lookup.getConnectionFactory(
CONNECTION_FACTORY_NAME);
ConnectionFactory connectionFactory = lookup.getConnectionFactory(CONNECTION_FACTORY_NAME);
assertThat(connectionFactory).isNotNull().isSameAs(expectedConnectionFactory);
}
@@ -68,13 +64,10 @@ public class MapConnectionFactoryLookupUnitTests {
connectionFactories.put(CONNECTION_FACTORY_NAME, overriddenConnectionFactory);
MapConnectionFactoryLookup lookup = new MapConnectionFactoryLookup();
lookup.setConnectionFactories(connectionFactories);
lookup.addConnectionFactory(CONNECTION_FACTORY_NAME, expectedConnectionFactory);
ConnectionFactory connectionFactory = lookup.getConnectionFactory(
CONNECTION_FACTORY_NAME);
ConnectionFactory connectionFactory = lookup.getConnectionFactory(CONNECTION_FACTORY_NAME);
assertThat(connectionFactory).isNotNull().isSameAs(expectedConnectionFactory);
}
@@ -83,20 +76,18 @@ public class MapConnectionFactoryLookupUnitTests {
public void getConnectionFactoryWhereSuppliedMapHasNonConnectionFactoryTypeUnderSpecifiedKey() {
Map connectionFactories = new HashMap<>();
connectionFactories.put(CONNECTION_FACTORY_NAME, new Object());
MapConnectionFactoryLookup lookup = new MapConnectionFactoryLookup(
connectionFactories);
MapConnectionFactoryLookup lookup = new MapConnectionFactoryLookup(connectionFactories);
assertThatThrownBy(
() -> lookup.getConnectionFactory(CONNECTION_FACTORY_NAME)).isInstanceOf(
ClassCastException.class);
assertThatThrownBy(() -> lookup.getConnectionFactory(CONNECTION_FACTORY_NAME))
.isInstanceOf(ClassCastException.class);
}
@Test
public void getConnectionFactoryWhereSuppliedMapHasNoEntryForSpecifiedKey() {
MapConnectionFactoryLookup lookup = new MapConnectionFactoryLookup();
assertThatThrownBy(
() -> lookup.getConnectionFactory(CONNECTION_FACTORY_NAME)).isInstanceOf(
ConnectionFactoryLookupFailureException.class);
assertThatThrownBy(() -> lookup.getConnectionFactory(CONNECTION_FACTORY_NAME))
.isInstanceOf(ConnectionFactoryLookupFailureException.class);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@@ -38,6 +38,7 @@ public abstract class AbstractDatabaseClientIntegrationTests {
private ConnectionFactory connectionFactory;
@BeforeEach
public void before() {
connectionFactory = createConnectionFactory();
@@ -52,8 +53,7 @@ public abstract class AbstractDatabaseClientIntegrationTests {
}
/**
* Creates a {@link ConnectionFactory} to be used in this test.
*
* Create a {@link ConnectionFactory} to be used in this test.
* @return the {@link ConnectionFactory} to be used in this test
*/
protected abstract ConnectionFactory createConnectionFactory();
@@ -66,11 +66,11 @@ public abstract class AbstractDatabaseClientIntegrationTests {
* <li>name varchar(255), nullable</li>
* <li>manual integer, nullable</li>
* </ul>
*
* @return the CREATE TABLE statement for table {@code legoset} with three columns.
*/
protected abstract String getCreateTableStatement();
@Test
public void executeInsert() {
DatabaseClient databaseClient = DatabaseClient.create(connectionFactory);

View File

@@ -51,12 +51,14 @@ public abstract class AbstractTransactionalDatabaseClientIntegrationTests {
AnnotationConfigApplicationContext context;
DatabaseClient databaseClient;
R2dbcTransactionManager transactionManager;
TransactionalOperator rxtx;
@BeforeEach
public void before() {
connectionFactory = createConnectionFactory();
context = new AnnotationConfigApplicationContext();
@@ -64,7 +66,6 @@ public abstract class AbstractTransactionalDatabaseClientIntegrationTests {
context.register(Config.class);
context.refresh();
Mono.from(connectionFactory.create())
.flatMapMany(connection -> Flux.from(connection.createStatement("DROP TABLE legoset").execute())
.flatMap(Result::getRowsUpdated)
@@ -82,6 +83,7 @@ public abstract class AbstractTransactionalDatabaseClientIntegrationTests {
context.close();
}
/**
* Create a {@link ConnectionFactory} to be used in this test.
* @return the {@link ConnectionFactory} to be used in this test.
@@ -107,6 +109,7 @@ public abstract class AbstractTransactionalDatabaseClientIntegrationTests {
return "INSERT INTO legoset (id, name, manual) VALUES(:id, :name, :manual)";
}
@Test
public void executeInsertInTransaction() {
Flux<Long> longFlux = databaseClient
@@ -131,7 +134,6 @@ public abstract class AbstractTransactionalDatabaseClientIntegrationTests {
@Test
public void shouldRollbackTransaction() {
Mono<Object> integerFlux = databaseClient.sql(getInsertIntoLegosetStatement())
.bind(0, 42055)
.bind(1, "SCHAUFELRADBAGGER")
@@ -154,7 +156,6 @@ public abstract class AbstractTransactionalDatabaseClientIntegrationTests {
@Test
public void shouldRollbackTransactionUsingTransactionalOperator() {
DatabaseClient databaseClient = DatabaseClient.create(connectionFactory);
TransactionalOperator transactionalOperator = TransactionalOperator
@@ -202,7 +203,6 @@ public abstract class AbstractTransactionalDatabaseClientIntegrationTests {
TransactionalOperator transactionalOperator(ReactiveTransactionManager transactionManager) {
return TransactionalOperator.create(transactionManager);
}
}
}

View File

@@ -77,7 +77,7 @@ class DefaultDatabaseClientUnitTests {
@BeforeEach
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
void before() {
ConnectionFactory connectionFactory = mock();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2023 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.
@@ -24,8 +24,7 @@ import io.r2dbc.spi.ConnectionFactory;
*
* @author Mark Paluch
*/
public class H2DatabaseClientIntegrationTests
extends AbstractDatabaseClientIntegrationTests {
public class H2DatabaseClientIntegrationTests extends AbstractDatabaseClientIntegrationTests {
public static String CREATE_TABLE_LEGOSET = "CREATE TABLE legoset (\n" //
+ " id serial CONSTRAINT id PRIMARY KEY,\n" //

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2023 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.
@@ -24,8 +24,7 @@ import io.r2dbc.spi.ConnectionFactory;
*
* @author Mark Paluch
*/
public class H2TransactionalDatabaseClientIntegrationTests
extends AbstractTransactionalDatabaseClientIntegrationTests {
public class H2TransactionalDatabaseClientIntegrationTests extends AbstractTransactionalDatabaseClientIntegrationTests {
public static String CREATE_TABLE_LEGOSET = "CREATE TABLE legoset (\n" //
+ " id integer CONSTRAINT id PRIMARY KEY,\n" //
@@ -43,4 +42,5 @@ public class H2TransactionalDatabaseClientIntegrationTests
protected String getCreateTableStatement() {
return CREATE_TABLE_LEGOSET;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 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.
@@ -33,7 +33,6 @@ class BindMarkersFactoryResolverUnitTests {
@Test
void shouldReturnBindMarkersFactoryForH2() {
BindMarkers bindMarkers = BindMarkersFactoryResolver
.resolve(new MockConnectionFactory("H2")).create();
@@ -42,7 +41,6 @@ class BindMarkersFactoryResolverUnitTests {
@Test
void shouldReturnBindMarkersFactoryForMariaDB() {
BindMarkers bindMarkers = BindMarkersFactoryResolver
.resolve(new MockConnectionFactory("MariaDB")).create();
@@ -51,7 +49,6 @@ class BindMarkersFactoryResolverUnitTests {
@Test
void shouldReturnBindMarkersFactoryForMicrosoftSQLServer() {
BindMarkers bindMarkers = BindMarkersFactoryResolver
.resolve(new MockConnectionFactory("Microsoft SQL Server")).create();
@@ -60,7 +57,6 @@ class BindMarkersFactoryResolverUnitTests {
@Test
void shouldReturnBindMarkersFactoryForMySQL() {
BindMarkers bindMarkers = BindMarkersFactoryResolver
.resolve(new MockConnectionFactory("MySQL")).create();
@@ -69,7 +65,6 @@ class BindMarkersFactoryResolverUnitTests {
@Test
void shouldReturnBindMarkersFactoryForOracle() {
BindMarkers bindMarkers = BindMarkersFactoryResolver
.resolve(new MockConnectionFactory("Oracle Database")).create();
@@ -78,13 +73,13 @@ class BindMarkersFactoryResolverUnitTests {
@Test
void shouldReturnBindMarkersFactoryForPostgreSQL() {
BindMarkers bindMarkers = BindMarkersFactoryResolver
.resolve(new MockConnectionFactory("PostgreSQL")).create();
assertThat(bindMarkers.next().getPlaceholder()).isEqualTo("$1");
}
static class MockConnectionFactory implements ConnectionFactory {
private final String driverName;
@@ -102,7 +97,6 @@ class BindMarkersFactoryResolverUnitTests {
public ConnectionFactoryMetadata getMetadata() {
return () -> driverName;
}
}
}

View File

@@ -26,7 +26,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Unit tests for {@link Bindings}.
*
@@ -35,8 +34,10 @@ import static org.mockito.Mockito.verify;
class BindingsUnitTests {
BindMarkersFactory markersFactory = BindMarkersFactory.indexed("$", 1);
BindTarget bindTarget = mock();
@Test
void shouldCreateBindings() {
MutableBindings bindings = new MutableBindings(markersFactory.create());