diff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc index bb919b2af7..638c8736b3 100644 --- a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc +++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc @@ -113,7 +113,8 @@ issue, because no compiler is involved, and you can declare When using `@Configuration` classes, the Java compiler places constraints on the configuration model, in that references to other beans must be valid Java syntax. -Fortunately, solving this problem is simple. As xref:core/beans/java/bean-annotation.adoc#beans-java-dependencies[we already discussed], +Fortunately, solving this problem is simple. As +xref:core/beans/java/bean-annotation.adoc#beans-java-dependencies[we already discussed], a `@Bean` method can have an arbitrary number of parameters that describe the bean dependencies. Consider the following more real-world scenario with several `@Configuration` classes, each depending on beans declared in the others: @@ -204,7 +205,6 @@ Kotlin:: ---- ====== - There is another way to achieve the same result. Remember that `@Configuration` classes are ultimately only another bean in the container: This means that they can take advantage of `@Autowired` and `@Value` injection and other features the same as any other bean. @@ -216,6 +216,11 @@ classes are processed quite early during the initialization of the context, and to be injected this way may lead to unexpected early initialization. Whenever possible, resort to parameter-based injection, as in the preceding example. +Avoid access to locally defined beans within a `@PostConstruct` method on the same configuration +class. This effectively leads to a circular reference since non-static `@Bean` methods semantically +require a fully initialized configuration class instance to be called on. With circular references +disallowed (e.g. in Spring Boot 2.6+), this may trigger a `BeanCurrentlyInCreationException`. + Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProcessor` definitions through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java b/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java index 23170a5f4d..b93f1159dd 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java @@ -105,8 +105,8 @@ import org.springframework.stereotype.Component; * * } * - *
{@code @Configuration} classes may not only be bootstrapped using - * component scanning, but may also themselves configure component scanning using + *
{@code @Configuration} classes may not only be bootstrapped using component + * scanning, but may also themselves configure component scanning using * the {@link ComponentScan @ComponentScan} annotation: * *
diff --git a/spring-core/src/main/java/org/springframework/util/backoff/ExponentialBackOff.java b/spring-core/src/main/java/org/springframework/util/backoff/ExponentialBackOff.java
index 897884ea41..739d51c614 100644
--- a/spring-core/src/main/java/org/springframework/util/backoff/ExponentialBackOff.java
+++ b/spring-core/src/main/java/org/springframework/util/backoff/ExponentialBackOff.java
@@ -20,9 +20,9 @@ import org.springframework.util.Assert;
/**
* Implementation of {@link BackOff} that increases the back off period for each
- * retry attempt. When the interval has reached the {@linkplain #setMaxInterval(long)
+ * retry attempt. When the interval has reached the {@linkplain #setMaxInterval
* max interval}, it is no longer increased. Stops retrying once the
- * {@linkplain #setMaxElapsedTime(long) max elapsed time} has been reached.
+ * {@linkplain #setMaxElapsedTime max elapsed time} has been reached.
*
* Example: The default interval is {@value #DEFAULT_INITIAL_INTERVAL} ms;
* the default multiplier is {@value #DEFAULT_MULTIPLIER}; and the default max
@@ -45,10 +45,10 @@ import org.springframework.util.Assert;
*
*
* Note that the default max elapsed time is {@link Long#MAX_VALUE}, and the
- * default maximum number of attempts is {@link Integer#MAX_VALUE}. Use
- * {@link #setMaxElapsedTime(long)} to limit the length of time that an instance
+ * default maximum number of attempts is {@link Integer#MAX_VALUE}.
+ * Use {@link #setMaxElapsedTime} to limit the length of time that an instance
* should accumulate before returning {@link BackOffExecution#STOP}. Alternatively,
- * use {@link #setMaxAttempts(int)} to limit the number of attempts. The execution
+ * use {@link #setMaxAttempts} to limit the number of attempts. The execution
* stops when either of those two limits is reached.
*
* @author Stephane Nicoll
@@ -117,7 +117,7 @@ public class ExponentialBackOff implements BackOff {
/**
- * The initial interval in milliseconds.
+ * Set the initial interval in milliseconds.
*/
public void setInitialInterval(long initialInterval) {
this.initialInterval = initialInterval;
@@ -131,7 +131,7 @@ public class ExponentialBackOff implements BackOff {
}
/**
- * The value to multiply the current interval by for each retry attempt.
+ * Set the value to multiply the current interval by for each retry attempt.
*/
public void setMultiplier(double multiplier) {
checkMultiplier(multiplier);
@@ -146,24 +146,24 @@ public class ExponentialBackOff implements BackOff {
}
/**
- * The maximum back off time.
+ * Set the maximum back off time in milliseconds.
*/
public void setMaxInterval(long maxInterval) {
this.maxInterval = maxInterval;
}
/**
- * Return the maximum back off time.
+ * Return the maximum back off time in milliseconds.
*/
public long getMaxInterval() {
return this.maxInterval;
}
/**
- * The maximum elapsed time in milliseconds after which a call to
+ * Set the maximum elapsed time in milliseconds after which a call to
* {@link BackOffExecution#nextBackOff()} returns {@link BackOffExecution#STOP}.
* @param maxElapsedTime the maximum elapsed time
- * @see #setMaxAttempts(int)
+ * @see #setMaxAttempts
*/
public void setMaxElapsedTime(long maxElapsedTime) {
this.maxElapsedTime = maxElapsedTime;
@@ -184,7 +184,7 @@ public class ExponentialBackOff implements BackOff {
* {@link BackOffExecution#nextBackOff()} returns {@link BackOffExecution#STOP}.
* @param maxAttempts the maximum number of attempts
* @since 6.1
- * @see #setMaxElapsedTime(long)
+ * @see #setMaxElapsedTime
*/
public void setMaxAttempts(int maxAttempts) {
this.maxAttempts = maxAttempts;
@@ -222,11 +222,9 @@ public class ExponentialBackOff implements BackOff {
@Override
public long nextBackOff() {
- if (this.currentElapsedTime >= getMaxElapsedTime()
- || this.attempts >= getMaxAttempts()) {
+ if (this.currentElapsedTime >= getMaxElapsedTime() || this.attempts >= getMaxAttempts()) {
return STOP;
}
-
long nextInterval = computeNextInterval();
this.currentElapsedTime += nextInterval;
this.attempts++;
@@ -254,7 +252,6 @@ public class ExponentialBackOff implements BackOff {
return Math.min(i, maxInterval);
}
-
@Override
public String toString() {
StringBuilder sb = new StringBuilder("ExponentialBackOff{");
diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java
index 76f7304e30..ae1f787509 100644
--- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java
+++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java
@@ -252,24 +252,24 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
if (ex instanceof JDBCConnectionException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
- if (ex instanceof SQLGrammarException hibJdbcEx) {
- return new InvalidDataAccessResourceUsageException(ex.getMessage() + "; SQL [" + hibJdbcEx.getSQL() + "]", ex);
+ if (ex instanceof SQLGrammarException hibEx) {
+ return new InvalidDataAccessResourceUsageException(ex.getMessage() + "; SQL [" + hibEx.getSQL() + "]", ex);
}
- if (ex instanceof QueryTimeoutException hibJdbcEx) {
- return new org.springframework.dao.QueryTimeoutException(ex.getMessage() + "; SQL [" + hibJdbcEx.getSQL() + "]", ex);
+ if (ex instanceof QueryTimeoutException hibEx) {
+ return new org.springframework.dao.QueryTimeoutException(ex.getMessage() + "; SQL [" + hibEx.getSQL() + "]", ex);
}
- if (ex instanceof LockAcquisitionException hibJdbcEx) {
- return new CannotAcquireLockException(ex.getMessage() + "; SQL [" + hibJdbcEx.getSQL() + "]", ex);
+ if (ex instanceof LockAcquisitionException hibEx) {
+ return new CannotAcquireLockException(ex.getMessage() + "; SQL [" + hibEx.getSQL() + "]", ex);
}
- if (ex instanceof PessimisticLockException hibJdbcEx) {
- return new PessimisticLockingFailureException(ex.getMessage() + "; SQL [" + hibJdbcEx.getSQL() + "]", ex);
+ if (ex instanceof PessimisticLockException hibEx) {
+ return new PessimisticLockingFailureException(ex.getMessage() + "; SQL [" + hibEx.getSQL() + "]", ex);
}
- if (ex instanceof ConstraintViolationException hibJdbcEx) {
- return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + hibJdbcEx.getSQL() +
- "]; constraint [" + hibJdbcEx.getConstraintName() + "]", ex);
+ if (ex instanceof ConstraintViolationException hibEx) {
+ return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + hibEx.getSQL() +
+ "]; constraint [" + hibEx.getConstraintName() + "]", ex);
}
- if (ex instanceof DataException hibJdbcEx) {
- return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + hibJdbcEx.getSQL() + "]", ex);
+ if (ex instanceof DataException hibEx) {
+ return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + hibEx.getSQL() + "]", ex);
}
// end of JDBCException subclass handling
diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java
index f3edbf16b9..38ef488cae 100644
--- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java
+++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java
@@ -209,7 +209,7 @@ public class R2dbcTransactionManager extends AbstractReactiveTransactionManager
connectionMono = Mono.just(txObject.getConnectionHolder().getConnection());
}
- return connectionMono.flatMap(con -> doBegin(definition, con)
+ return connectionMono.flatMap(con -> doBegin(con, txObject, definition)
.then(prepareTransactionalConnection(con, definition))
.doOnSuccess(v -> {
txObject.getConnectionHolder().setTransactionActive(true);
@@ -233,7 +233,10 @@ public class R2dbcTransactionManager extends AbstractReactiveTransactionManager
}).then();
}
- private Mono