diff --git a/framework-platform/framework-platform.gradle b/framework-platform/framework-platform.gradle
index 88e1ec38e77..5d2e712558e 100644
--- a/framework-platform/framework-platform.gradle
+++ b/framework-platform/framework-platform.gradle
@@ -26,7 +26,7 @@ dependencies {
constraints {
api("com.fasterxml:aalto-xml:1.3.4")
api("com.fasterxml.woodstox:woodstox-core:6.7.0")
- api("com.github.ben-manes.caffeine:caffeine:3.2.2")
+ api("com.github.ben-manes.caffeine:caffeine:3.2.3")
api("com.github.librepdf:openpdf:1.3.43")
api("com.google.code.findbugs:findbugs:3.0.1")
api("com.google.code.findbugs:jsr305:3.0.2")
@@ -124,7 +124,7 @@ dependencies {
api("org.hibernate.orm:hibernate-core:7.2.0.CR1")
api("org.hibernate.validator:hibernate-validator:9.1.0.CR1")
api("org.hsqldb:hsqldb:2.7.4")
- api("org.htmlunit:htmlunit:4.17.0")
+ api("org.htmlunit:htmlunit:4.18.0")
api("org.javamoney:moneta:1.4.4")
api("org.jboss.logging:jboss-logging:3.6.1.Final")
api("org.jruby:jruby:10.0.2.0")
@@ -135,8 +135,8 @@ dependencies {
api("org.python:jython-standalone:2.7.4")
api("org.quartz-scheduler:quartz:2.3.2")
api("org.reactivestreams:reactive-streams:1.0.4")
- api("org.seleniumhq.selenium:htmlunit3-driver:4.36.1")
- api("org.seleniumhq.selenium:selenium-java:4.36.0")
+ api("org.seleniumhq.selenium:htmlunit3-driver:4.38.0")
+ api("org.seleniumhq.selenium:selenium-java:4.38.0")
api("org.skyscreamer:jsonassert:1.5.3")
api("org.testng:testng:7.11.0")
api("org.webjars:underscorejs:1.8.3")
diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurer.java b/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurer.java
index fea24a03fc9..37ffbd4149d 100644
--- a/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurer.java
+++ b/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurer.java
@@ -24,14 +24,14 @@ import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.interceptor.KeyGenerator;
/**
- * Interface to be implemented by @{@link org.springframework.context.annotation.Configuration
- * Configuration} classes annotated with @{@link EnableCaching} that wish or need to specify
- * explicitly how caches are resolved and how keys are generated for annotation-driven
- * cache management.
+ * Interface to be implemented for explicitly specifying how caches are resolved
+ * and how keys are generated for annotation-driven cache management.
*
- *
See @{@link EnableCaching} for general examples and context; see
- * {@link #cacheManager()}, {@link #cacheResolver()}, {@link #keyGenerator()}, and
- * {@link #errorHandler()} for detailed instructions.
+ *
Typically implemented by @{@link org.springframework.context.annotation.Configuration
+ * Configuration} classes annotated with @{@link EnableCaching}.
+ * See @{@link EnableCaching} for general examples and context; see
+ * {@link #cacheManager()}, {@link #cacheResolver()}, {@link #keyGenerator()},
+ * and {@link #errorHandler()} for detailed instructions.
*
*
NOTE: A {@code CachingConfigurer} will get initialized early.
* Do not inject common dependencies into autowired fields directly; instead, consider
diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurer.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurer.java
index 6850303e772..f259b22bd25 100644
--- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurer.java
+++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncConfigurer.java
@@ -23,13 +23,18 @@ import org.jspecify.annotations.Nullable;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
/**
- * Interface to be implemented by @{@link org.springframework.context.annotation.Configuration
- * Configuration} classes annotated with @{@link EnableAsync} that wish to customize the
- * {@link Executor} instance used when processing async method invocations or the
- * {@link AsyncUncaughtExceptionHandler} instance used to process exception thrown from
- * async method with {@code void} return type.
+ * Interface to be implemented for customizing the {@link Executor} instance used when
+ * processing async method invocations or the {@link AsyncUncaughtExceptionHandler}
+ * instance used to process exceptions thrown from async methods with a {@code void}
+ * return type.
*
- *
See @{@link EnableAsync} for usage examples.
+ *
Typically implemented by @{@link org.springframework.context.annotation.Configuration
+ * Configuration} classes annotated with @{@link EnableAsync}.
+ * See the @{@link EnableAsync} javadoc for usage examples.
+ *
+ *
NOTE: An {@code AsyncConfigurer} will get initialized early.
+ * Do not inject common dependencies into autowired fields directly; instead, consider
+ * declaring a lazy {@link org.springframework.beans.factory.ObjectProvider} for those.
*
* @author Chris Beams
* @author Stephane Nicoll
diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessor.java
index c4ccbad1ddf..c6f52fd611f 100644
--- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessor.java
+++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessor.java
@@ -65,7 +65,6 @@ import org.springframework.util.ReflectionUtils;
* @author Sebastien Deleuze
* @since 6.0
*/
-@SuppressWarnings("unchecked")
class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
private static final boolean JPA_PRESENT = ClassUtils.isPresent("jakarta.persistence.Entity",
@@ -82,12 +81,12 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
return null;
}
+
private static final class JpaManagedTypesBeanRegistrationCodeFragments extends BeanRegistrationCodeFragmentsDecorator {
private static final List> CALLBACK_TYPES = List.of(PreUpdate.class,
PostUpdate.class, PrePersist.class, PostPersist.class, PreRemove.class, PostRemove.class, PostLoad.class);
-
private static final ParameterizedTypeName LIST_OF_STRINGS_TYPE = ParameterizedTypeName.get(List.class, String.class);
private final RegisteredBean registeredBean;
@@ -102,8 +101,8 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
@Override
public CodeBlock generateInstanceSupplierCode(GenerationContext generationContext,
- BeanRegistrationCode beanRegistrationCode,
- boolean allowDirectSupplierShortcut) {
+ BeanRegistrationCode beanRegistrationCode, boolean allowDirectSupplierShortcut) {
+
PersistenceManagedTypes persistenceManagedTypes = this.registeredBean.getBeanFactory()
.getBean(this.registeredBean.getBeanName(), PersistenceManagedTypes.class);
contributeHints(generationContext.getRuntimeHints(),
@@ -140,7 +139,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
contributeHibernateHints(hints, classLoader, managedClass);
}
catch (ClassNotFoundException ex) {
- throw new IllegalArgumentException("Failed to instantiate the managed class: " + managedClassName, ex);
+ throw new IllegalArgumentException("Failed to instantiate JPA managed class: " + managedClassName, ex);
}
}
}
@@ -149,7 +148,8 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
EntityListeners entityListeners = AnnotationUtils.findAnnotation(managedClass, EntityListeners.class);
if (entityListeners != null) {
for (Class> entityListener : entityListeners.value()) {
- hints.reflection().registerType(entityListener, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS);
+ hints.reflection().registerType(entityListener,
+ MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS);
}
}
}
@@ -169,12 +169,14 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
}
Convert convertClassAnnotation = AnnotationUtils.findAnnotation(managedClass, Convert.class);
if (convertClassAnnotation != null) {
- reflectionHints.registerType(convertClassAnnotation.converter(), MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
+ reflectionHints.registerType(convertClassAnnotation.converter(),
+ MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
}
ReflectionUtils.doWithFields(managedClass, field -> {
Convert convertFieldAnnotation = AnnotationUtils.findAnnotation(field, Convert.class);
if (convertFieldAnnotation != null && convertFieldAnnotation.converter() != AttributeConverter.class) {
- reflectionHints.registerType(convertFieldAnnotation.converter(), MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
+ reflectionHints.registerType(convertFieldAnnotation.converter(),
+ MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
}
});
}
@@ -186,11 +188,11 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
method -> CALLBACK_TYPES.stream().anyMatch(method::isAnnotationPresent));
}
- @SuppressWarnings("unchecked")
private void contributeHibernateHints(RuntimeHints hints, @Nullable ClassLoader classLoader, Class> managedClass) {
ReflectionHints reflection = hints.reflection();
- Class extends Annotation> embeddableInstantiatorClass = loadClass("org.hibernate.annotations.EmbeddableInstantiator", classLoader);
+ Class extends Annotation> embeddableInstantiatorClass =
+ loadClass("org.hibernate.annotations.EmbeddableInstantiator", classLoader);
if (embeddableInstantiatorClass != null) {
registerForReflection(reflection,
AnnotationUtils.findAnnotation(managedClass, embeddableInstantiatorClass), "value");
@@ -204,7 +206,8 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
AnnotationUtils.findAnnotation(method, embeddableInstantiatorClass), "value"));
}
- Class extends Annotation> valueGenerationTypeClass = loadClass("org.hibernate.annotations.ValueGenerationType", classLoader);
+ Class extends Annotation> valueGenerationTypeClass =
+ loadClass("org.hibernate.annotations.ValueGenerationType", classLoader);
if (valueGenerationTypeClass != null) {
ReflectionUtils.doWithFields(managedClass, field -> registerForReflection(reflection,
AnnotationUtils.findAnnotation(field, valueGenerationTypeClass), "generatedBy"));
@@ -212,7 +215,8 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
AnnotationUtils.findAnnotation(method, valueGenerationTypeClass), "generatedBy"));
}
- Class extends Annotation> idGeneratorTypeClass = loadClass("org.hibernate.annotations.IdGeneratorType", classLoader);
+ Class extends Annotation> idGeneratorTypeClass =
+ loadClass("org.hibernate.annotations.IdGeneratorType", classLoader);
if (idGeneratorTypeClass != null) {
ReflectionUtils.doWithFields(managedClass, field -> registerForReflection(reflection,
AnnotationUtils.findAnnotation(field, idGeneratorTypeClass), "value"));
@@ -220,7 +224,8 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
AnnotationUtils.findAnnotation(method, idGeneratorTypeClass), "value"));
}
- Class extends Annotation> attributeBinderTypeClass = loadClass("org.hibernate.annotations.AttributeBinderType", classLoader);
+ Class extends Annotation> attributeBinderTypeClass =
+ loadClass("org.hibernate.annotations.AttributeBinderType", classLoader);
if (attributeBinderTypeClass != null) {
ReflectionUtils.doWithFields(managedClass, field -> registerForReflection(reflection,
AnnotationUtils.findAnnotation(field, attributeBinderTypeClass), "binder"));
@@ -229,6 +234,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
}
}
+ @SuppressWarnings("unchecked")
private static @Nullable Class extends Annotation> loadClass(String className, @Nullable ClassLoader classLoader) {
try {
return (Class extends Annotation>) ClassUtils.forName(className, classLoader);
@@ -238,7 +244,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
}
}
- @SuppressWarnings("NullAway") // Not null assertion performed in ReflectionHints.registerType
+ @SuppressWarnings("NullAway") // Not-null assertion performed in ReflectionHints.registerType
private void registerForReflection(ReflectionHints reflection, @Nullable Annotation annotation, String attribute) {
if (annotation == null) {
return;
@@ -247,4 +253,5 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
reflection.registerType(type, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
}
}
+
}
diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessorTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessorTests.java
index 725c101bfda..6b45c4c81fb 100644
--- a/spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessorTests.java
+++ b/spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessorTests.java
@@ -66,8 +66,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
GenericApplicationContext context = new AnnotationConfigApplicationContext();
context.registerBean(JpaDomainConfiguration.class);
compile(context, (initializer, compiled) -> {
- GenericApplicationContext freshApplicationContext = toFreshApplicationContext(
- initializer);
+ GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
PersistenceManagedTypes persistenceManagedTypes = freshApplicationContext.getBean(
"persistenceManagedTypes", PersistenceManagedTypes.class);
assertThat(persistenceManagedTypes.getManagedClassNames()).containsExactlyInAnyOrder(
@@ -121,6 +120,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
@SuppressWarnings("unchecked")
private void compile(GenericApplicationContext applicationContext,
BiConsumer, Compiled> result) {
+
ApplicationContextAotGenerator generator = new ApplicationContextAotGenerator();
TestGenerationContext generationContext = new TestGenerationContext();
generator.processAheadOfTime(applicationContext, generationContext);
@@ -131,6 +131,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
private GenericApplicationContext toFreshApplicationContext(
ApplicationContextInitializer initializer) {
+
GenericApplicationContext freshApplicationContext = new GenericApplicationContext();
initializer.initialize(freshApplicationContext);
freshApplicationContext.refresh();
@@ -145,24 +146,6 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
}
- public static class JpaDomainConfiguration extends AbstractEntityManagerWithPackagesToScanConfiguration {
-
- @Override
- protected String packageToScan() {
- return "org.springframework.orm.jpa.domain";
- }
- }
-
-
- public static class HibernateDomainConfiguration extends AbstractEntityManagerWithPackagesToScanConfiguration {
-
- @Override
- protected String packageToScan() {
- return "org.springframework.orm.jpa.hibernate.domain";
- }
- }
-
-
public abstract static class AbstractEntityManagerWithPackagesToScanConfiguration {
protected boolean scanningInvoked;
@@ -182,13 +165,13 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
@Bean
public PersistenceManagedTypes persistenceManagedTypes(ResourceLoader resourceLoader) {
this.scanningInvoked = true;
- return new PersistenceManagedTypesScanner(resourceLoader)
- .scan(packageToScan());
+ return new PersistenceManagedTypesScanner(resourceLoader).scan(packageToScan());
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
JpaVendorAdapter jpaVendorAdapter, PersistenceManagedTypes persistenceManagedTypes) {
+
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
@@ -199,4 +182,22 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
protected abstract String packageToScan();
}
+
+ public static class JpaDomainConfiguration extends AbstractEntityManagerWithPackagesToScanConfiguration {
+
+ @Override
+ protected String packageToScan() {
+ return "org.springframework.orm.jpa.domain";
+ }
+ }
+
+
+ public static class HibernateDomainConfiguration extends AbstractEntityManagerWithPackagesToScanConfiguration {
+
+ @Override
+ protected String packageToScan() {
+ return "org.springframework.orm.jpa.hibernate.domain";
+ }
+ }
+
}
diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurer.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurer.java
index 5c721b2d963..a56e655fb13 100644
--- a/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurer.java
+++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurer.java
@@ -19,15 +19,17 @@ package org.springframework.transaction.annotation;
import org.springframework.transaction.TransactionManager;
/**
- * Interface to be implemented by @{@link org.springframework.context.annotation.Configuration
- * Configuration} classes annotated with @{@link EnableTransactionManagement} that wish to
- * (or need to) explicitly specify the default {@code PlatformTransactionManager} bean
- * (or {@code ReactiveTransactionManager} bean) to be used for annotation-driven
- * transaction management, as opposed to the default approach of a by-type lookup.
- * One reason this might be necessary is if there are two {@code PlatformTransactionManager}
- * beans (or two {@code ReactiveTransactionManager} beans) present in the container.
+ * Interface to be implemented for explicitly specifying the default
+ * {@link org.springframework.transaction.PlatformTransactionManager} bean
+ * (or {@link org.springframework.transaction.ReactiveTransactionManager} bean)
+ * to be used for annotation-driven transaction management, as opposed to the
+ * default approach of a by-type lookup. One reason this might be necessary is
+ * if there are two {@code PlatformTransactionManager} beans (or two
+ * {@code ReactiveTransactionManager} beans) present in the container.
*
- * See @{@link EnableTransactionManagement} for general examples and context;
+ *
Typically implemented by @{@link org.springframework.context.annotation.Configuration
+ * Configuration} classes annotated with @{@link EnableTransactionManagement}.
+ * See @{@link EnableTransactionManagement} for general examples and context;
* see {@link #annotationDrivenTransactionManager()} for detailed instructions.
*
*
NOTE: A {@code TransactionManagementConfigurer} will get initialized early.