From cca8fbd3dec88c88da8669ff0cfffa755a82aebd Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 2 Jun 2023 23:25:08 +0200 Subject: [PATCH 1/4] Log warning in case of standard Commons Logging discovery Closes gh-30575 --- .../org/apache/commons/logging/LogFactoryService.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spring-jcl/src/main/java/org/apache/commons/logging/LogFactoryService.java b/spring-jcl/src/main/java/org/apache/commons/logging/LogFactoryService.java index ef82eb90c7..68561d67b5 100644 --- a/spring-jcl/src/main/java/org/apache/commons/logging/LogFactoryService.java +++ b/spring-jcl/src/main/java/org/apache/commons/logging/LogFactoryService.java @@ -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 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()); From b738a202338571b897cd64df3cfe34f11308d8a5 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 2 Jun 2023 23:25:35 +0200 Subject: [PATCH 2/4] Consistently publish events from CompletableFuture Closes gh-30578 --- .../context/event/ApplicationListenerMethodAdapter.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java index ee8783a096..f61a767bcc 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java +++ b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java @@ -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 { @Override From c68552556f98b9b5b036200279e9d07e8ef9222e Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 2 Jun 2023 23:26:58 +0200 Subject: [PATCH 3/4] Revise TargetSource implementations for proper nullability Includes hashCode optimization in AbstractBeanFactoryBasedTargetSource. Includes ThreadLocal naming fix in ThreadLocalTargetSource. Closes gh-30576 Closes gh-30581 --- ...ctBeanFactoryBasedTargetSourceCreator.java | 10 ++++++++-- .../AbstractBeanFactoryBasedTargetSource.java | 20 +++++++++++-------- .../AbstractLazyCreationTargetSource.java | 3 ++- .../aop/target/EmptyTargetSource.java | 1 + .../aop/target/HotSwappableTargetSource.java | 7 +++---- .../aop/target/SingletonTargetSource.java | 9 ++------- .../aop/target/ThreadLocalTargetSource.java | 9 +++++++-- 7 files changed, 35 insertions(+), 24 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/target/AbstractBeanFactoryBasedTargetSourceCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/target/AbstractBeanFactoryBasedTargetSourceCreator.java index 6dbb6d8bd9..650b40736c 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/target/AbstractBeanFactoryBasedTargetSourceCreator.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/target/AbstractBeanFactoryBasedTargetSourceCreator.java @@ -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())); } } diff --git a/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java index 9a9679fd29..4c78958795 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java @@ -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(); } diff --git a/spring-aop/src/main/java/org/springframework/aop/target/AbstractLazyCreationTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/AbstractLazyCreationTargetSource.java index f742a106ba..8246e1e626 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/AbstractLazyCreationTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/AbstractLazyCreationTargetSource.java @@ -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; diff --git a/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java index a78e6e4b40..b9f45e2a57 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java @@ -70,6 +70,7 @@ public final class EmptyTargetSource implements TargetSource, Serializable { // Instance implementation //--------------------------------------------------------------------- + @Nullable private final Class targetClass; private final boolean isStatic; diff --git a/spring-aop/src/main/java/org/springframework/aop/target/HotSwappableTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/HotSwappableTargetSource.java index 8242bbfcac..1a1a2fa755 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/HotSwappableTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/HotSwappableTargetSource.java @@ -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))); } diff --git a/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java index 8ebe6d2991..e1b2ae6a56 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/SingletonTargetSource.java @@ -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))); } /** diff --git a/spring-aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java index 5c4b03c784..7edfc0aff6 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java @@ -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 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. From 4b8adf2dccd37285e4b68e2796620be521844e2f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 2 Jun 2023 23:28:14 +0200 Subject: [PATCH 4/4] Polishing --- .../AspectJAdviceParameterNameDiscoverer.java | 2 +- .../beans/TypeConverterSupport.java | 4 +- .../support/DefaultSingletonBeanRegistry.java | 4 +- .../support/DisposableBeanAdapter.java | 6 +- .../support/AbstractApplicationContext.java | 4 +- .../annotation/configuration/ImportTests.java | 19 +++++- .../springframework/core/MethodParameter.java | 1 + .../ConnectionFactoryUtilsUnitTests.java | 4 +- .../DelegatingConnectionFactoryUnitTests.java | 3 +- .../R2dbcTransactionManagerUnitTests.java | 6 +- .../SingleConnectionFactoryUnitTests.java | 10 +-- ...nAwareConnectionFactoryProxyUnitTests.java | 2 + .../init/AbstractDatabasePopulatorTests.java | 61 +++++++++---------- .../init/CompositeDatabasePopulatorTests.java | 1 + .../H2DatabasePopulatorIntegrationTests.java | 6 +- .../connection/init/ScriptUtilsUnitTests.java | 18 +++--- ...ractRoutingConnectionFactoryUnitTests.java | 20 +++--- ...ctoryConnectionFactoryLookupUnitTests.java | 30 ++++----- .../lookup/DummyConnectionFactory.java | 6 +- .../MapConnectionFactoryLookupUnitTests.java | 31 ++++------ ...bstractDatabaseClientIntegrationTests.java | 8 +-- ...ctionalDatabaseClientIntegrationTests.java | 10 +-- .../core/DefaultDatabaseClientUnitTests.java | 2 +- .../H2DatabaseClientIntegrationTests.java | 5 +- ...ctionalDatabaseClientIntegrationTests.java | 6 +- .../BindMarkersFactoryResolverUnitTests.java | 10 +-- .../r2dbc/core/binding/BindingsUnitTests.java | 3 +- 27 files changed, 134 insertions(+), 148 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java index d7fc989d44..ec9b634ff8 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java @@ -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--; } diff --git a/spring-beans/src/main/java/org/springframework/beans/TypeConverterSupport.java b/spring-beans/src/main/java/org/springframework/beans/TypeConverterSupport.java index e99c875e5f..c0ad9408e9 100644 --- a/spring-beans/src/main/java/org/springframework/beans/TypeConverterSupport.java +++ b/spring-beans/src/main/java/org/springframework/beans/TypeConverterSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 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. @@ -63,8 +63,8 @@ public abstract class TypeConverterSupport extends PropertyEditorRegistrySupport (field != null ? new TypeDescriptor(field) : TypeDescriptor.valueOf(requiredType))); } - @Nullable @Override + @Nullable public T convertIfNecessary(@Nullable Object value, @Nullable Class requiredType, @Nullable TypeDescriptor typeDescriptor) throws TypeMismatchException { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java index 0c16e50487..98ca29c7a4 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java @@ -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 disposableBeans = new LinkedHashMap<>(); + private final Map disposableBeans = new LinkedHashMap<>(); /** Map between containing bean names: bean name to Set of bean names that the bean contains. */ private final Map> 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); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java index c13d5c9600..0d2bc2adeb 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java @@ -65,8 +65,8 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { private static final String SHUTDOWN_METHOD_NAME = "shutdown"; - private static final Log logger = LogFactory.getLog(DisposableBeanAdapter.class); + private static final Log logger = LogFactory.getLog(DisposableBeanAdapter.class); private final Object bean; @@ -240,7 +240,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { } } else if (this.destroyMethodNames != null) { - for (String destroyMethodName: this.destroyMethodNames) { + for (String destroyMethodName : this.destroyMethodNames) { Method destroyMethod = determineDestroyMethod(destroyMethodName); if (destroyMethod != null) { invokeCustomDestroyMethod( @@ -288,7 +288,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { */ private void invokeCustomDestroyMethod(Method destroyMethod) { int paramCount = destroyMethod.getParameterCount(); - final Object[] args = new Object[paramCount]; + Object[] args = new Object[paramCount]; if (paramCount == 1) { args[0] = Boolean.TRUE; } diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index 871d166e51..00bccae17b 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -463,7 +463,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader @Override public void setApplicationStartup(ApplicationStartup applicationStartup) { - Assert.notNull(applicationStartup, "applicationStartup must not be null"); + Assert.notNull(applicationStartup, "ApplicationStartup must not be null"); this.applicationStartup = applicationStartup; } @@ -946,7 +946,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader * onRefresh() method and publishing the * {@link org.springframework.context.event.ContextRefreshedEvent}. */ - @SuppressWarnings("deprecation") protected void finishRefresh() { // Clear context-level resource caches (such as ASM metadata from scanning). clearResourceCaches(); @@ -1047,7 +1046,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)) { diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportTests.java index 0056376f55..04638e1822 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ImportTests.java @@ -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 { diff --git a/spring-core/src/main/java/org/springframework/core/MethodParameter.java b/spring-core/src/main/java/org/springframework/core/MethodParameter.java index 556005cf3d..8004b87a2f 100644 --- a/spring-core/src/main/java/org/springframework/core/MethodParameter.java +++ b/spring-core/src/main/java/org/springframework/core/MethodParameter.java @@ -780,6 +780,7 @@ public class MethodParameter { return new MethodParameter(this); } + /** * Create a new MethodParameter for the given method or constructor. *

This is a convenience factory method for scenarios where a diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/ConnectionFactoryUtilsUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/ConnectionFactoryUtilsUnitTests.java index 3362e0c1fe..9292f11dd3 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/ConnectionFactoryUtilsUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/ConnectionFactoryUtilsUnitTests.java @@ -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 { } } diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/DelegatingConnectionFactoryUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/DelegatingConnectionFactoryUnitTests.java index faba0369ea..d02c0ffa66 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/DelegatingConnectionFactoryUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/DelegatingConnectionFactoryUnitTests.java @@ -40,7 +40,7 @@ class DelegatingConnectionFactoryUnitTests { @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) void shouldDelegateGetConnection() { Mono 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) { diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/R2dbcTransactionManagerUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/R2dbcTransactionManagerUnitTests.java index 9e222589b1..857744d828 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/R2dbcTransactionManagerUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/R2dbcTransactionManagerUnitTests.java @@ -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); } - } } diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/SingleConnectionFactoryUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/SingleConnectionFactoryUnitTests.java index 9bc4a9582f..dec679b764 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/SingleConnectionFactoryUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/SingleConnectionFactoryUnitTests.java @@ -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) diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxyUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxyUnitTests.java index 9344bb42bb..8dd4794d39 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxyUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxyUnitTests.java @@ -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() diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/AbstractDatabasePopulatorTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/AbstractDatabasePopulatorTests.java index fe281681b5..ce7eb16590 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/AbstractDatabasePopulatorTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/AbstractDatabasePopulatorTests.java @@ -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(); - } - } - } diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/CompositeDatabasePopulatorTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/CompositeDatabasePopulatorTests.java index c149eb4a77..5f68223318 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/CompositeDatabasePopulatorTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/CompositeDatabasePopulatorTests.java @@ -52,6 +52,7 @@ class CompositeDatabasePopulatorTests { when(mockedDatabasePopulator2.populate(mockedConnection)).thenReturn(Mono.empty()); } + @Test void addPopulators() { CompositeDatabasePopulator populator = new CompositeDatabasePopulator(); diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/H2DatabasePopulatorIntegrationTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/H2DatabasePopulatorIntegrationTests.java index e11cbe95cb..d34f7fcf04 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/H2DatabasePopulatorIntegrationTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/H2DatabasePopulatorIntegrationTests.java @@ -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 diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ScriptUtilsUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ScriptUtilsUnitTests.java index 63fe4ecd96..41dd48477d 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ScriptUtilsUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ScriptUtilsUnitTests.java @@ -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 statements = ScriptUtils.splitSqlScript(null, script, ";", commentPrefixes, DEFAULT_BLOCK_COMMENT_START_DELIMITER, - DEFAULT_BLOCK_COMMENT_END_DELIMITER); + List 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 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); } } diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactoryUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactoryUnitTests.java index 43ea3141a1..ecadb88232 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactoryUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactoryUnitTests.java @@ -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 diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/BeanFactoryConnectionFactoryLookupUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/BeanFactoryConnectionFactoryLookupUnitTests.java index 174447796a..2ccb13cb97 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/BeanFactoryConnectionFactoryLookupUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/BeanFactoryConnectionFactoryLookupUnitTests.java @@ -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); } } diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/DummyConnectionFactory.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/DummyConnectionFactory.java index 1d3b8a849b..b2f1229cf6 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/DummyConnectionFactory.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/DummyConnectionFactory.java @@ -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. - *

- * All methods throw {@link UnsupportedOperationException}. + * + *

All methods throw {@link UnsupportedOperationException}. * * @author Mark Paluch */ diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/MapConnectionFactoryLookupUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/MapConnectionFactoryLookupUnitTests.java index bf2dcd5ff6..89815b71c2 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/MapConnectionFactoryLookupUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/MapConnectionFactoryLookupUnitTests.java @@ -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 connectionFactories = lookup.getConnectionFactories(); assertThatThrownBy(() -> connectionFactories.put("", - new DummyConnectionFactory())).isInstanceOf( - UnsupportedOperationException.class); + new DummyConnectionFactory())).isInstanceOf(UnsupportedOperationException.class); } @Test public void shouldLookupConnectionFactory() { Map 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); } + } diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/AbstractDatabaseClientIntegrationTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/AbstractDatabaseClientIntegrationTests.java index 63844c103a..e18ed98952 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/AbstractDatabaseClientIntegrationTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/AbstractDatabaseClientIntegrationTests.java @@ -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 { *

  • name varchar(255), nullable
  • *
  • manual integer, nullable
  • * - * * @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); diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/AbstractTransactionalDatabaseClientIntegrationTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/AbstractTransactionalDatabaseClientIntegrationTests.java index 13831337cf..081ec90ab3 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/AbstractTransactionalDatabaseClientIntegrationTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/AbstractTransactionalDatabaseClientIntegrationTests.java @@ -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 longFlux = databaseClient @@ -131,7 +134,6 @@ public abstract class AbstractTransactionalDatabaseClientIntegrationTests { @Test public void shouldRollbackTransaction() { - Mono 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); } - } } diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientUnitTests.java index a6c608cbbd..8ebf0f1a83 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientUnitTests.java @@ -77,7 +77,7 @@ class DefaultDatabaseClientUnitTests { @BeforeEach - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) void before() { ConnectionFactory connectionFactory = mock(); diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/H2DatabaseClientIntegrationTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/H2DatabaseClientIntegrationTests.java index 7bf3f3883c..e808e5e1aa 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/H2DatabaseClientIntegrationTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/H2DatabaseClientIntegrationTests.java @@ -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" // diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/H2TransactionalDatabaseClientIntegrationTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/H2TransactionalDatabaseClientIntegrationTests.java index e326f851ab..b179f677a4 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/H2TransactionalDatabaseClientIntegrationTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/H2TransactionalDatabaseClientIntegrationTests.java @@ -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; } + } diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolverUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolverUnitTests.java index 2314b782b7..85fb67bbb5 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolverUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolverUnitTests.java @@ -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; } - } } diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindingsUnitTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindingsUnitTests.java index 95bddc7535..a5daced20e 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindingsUnitTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/binding/BindingsUnitTests.java @@ -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());