mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-09-17 12:09:16 +00:00
Merge branch '4.0.x' into 4.1.x
Closes gh-51544
This commit is contained in:
+38
@@ -61,8 +61,15 @@ import com.tngtech.archunit.lang.syntax.elements.ClassesShould;
|
|||||||
import com.tngtech.archunit.lang.syntax.elements.GivenMethodsConjunction;
|
import com.tngtech.archunit.lang.syntax.elements.GivenMethodsConjunction;
|
||||||
import com.tngtech.archunit.library.dependencies.SlicesRuleDefinition;
|
import com.tngtech.archunit.library.dependencies.SlicesRuleDefinition;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||||
|
import org.springframework.beans.factory.BeanFactoryAware;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.EnvironmentAware;
|
||||||
|
import org.springframework.context.ResourceLoaderAware;
|
||||||
|
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||||
|
import org.springframework.context.annotation.ImportSelector;
|
||||||
import org.springframework.context.annotation.Role;
|
import org.springframework.context.annotation.Role;
|
||||||
|
import org.springframework.core.type.filter.TypeFilter;
|
||||||
import org.springframework.lang.CheckReturnValue;
|
import org.springframework.lang.CheckReturnValue;
|
||||||
import org.springframework.util.ResourceUtils;
|
import org.springframework.util.ResourceUtils;
|
||||||
|
|
||||||
@@ -111,6 +118,7 @@ final class ArchitectureRules {
|
|||||||
rules.add(autoConfigurationClassesShouldBePublicAndFinal());
|
rules.add(autoConfigurationClassesShouldBePublicAndFinal());
|
||||||
rules.add(autoConfigurationClassesShouldHaveNoPublicMembers());
|
rules.add(autoConfigurationClassesShouldHaveNoPublicMembers());
|
||||||
rules.add(testAutoConfigurationClassesShouldBePackagePrivateAndFinal());
|
rules.add(testAutoConfigurationClassesShouldBePackagePrivateAndFinal());
|
||||||
|
rules.add(importParticipantsShouldOnlyImplementAwareInterfacesIfTheyArePublic());
|
||||||
return List.copyOf(rules);
|
return List.copyOf(rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,6 +307,36 @@ final class ArchitectureRules {
|
|||||||
.because(shouldUse("String.toLowerCase(Locale.ROOT)"));
|
.because(shouldUse("String.toLowerCase(Locale.ROOT)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ArchRule importParticipantsShouldOnlyImplementAwareInterfacesIfTheyArePublic() {
|
||||||
|
return ArchRuleDefinition.classes()
|
||||||
|
.that(areImportParticipants())
|
||||||
|
.and()
|
||||||
|
.areNotPublic()
|
||||||
|
.should(notDirectlyImplementAwareInterfaces())
|
||||||
|
.allowEmptyShould(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DescribedPredicate<JavaClass> areImportParticipants() {
|
||||||
|
return JavaClass.Predicates.implement(ImportBeanDefinitionRegistrar.class)
|
||||||
|
.or(JavaClass.Predicates.implement(ImportSelector.class))
|
||||||
|
.or(JavaClass.Predicates.implement(TypeFilter.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ArchCondition<JavaClass> notDirectlyImplementAwareInterfaces() {
|
||||||
|
Set<String> awareNames = Set.of(BeanClassLoaderAware.class.getName(), BeanFactoryAware.class.getName(),
|
||||||
|
EnvironmentAware.class.getName(), ResourceLoaderAware.class.getName());
|
||||||
|
return ArchCondition
|
||||||
|
.from(DescribedPredicate.describe("not directly implement BeanClassLoaderAware, BeanFactoryAware,"
|
||||||
|
+ " EnvironmentAware, or ResourceLoaderAware", (javaClass) -> {
|
||||||
|
for (JavaClass rawInterface : javaClass.getRawInterfaces()) {
|
||||||
|
if (awareNames.contains(rawInterface.getFullName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
private static ArchRule conditionalOnMissingBeanShouldNotSpecifyOnlyATypeThatIsTheSameAsMethodReturnType(
|
private static ArchRule conditionalOnMissingBeanShouldNotSpecifyOnlyATypeThatIsTheSameAsMethodReturnType(
|
||||||
String annotation) {
|
String annotation) {
|
||||||
return methodsThatAreAnnotatedWith(annotation)
|
return methodsThatAreAnnotatedWith(annotation)
|
||||||
|
|||||||
+3
-6
@@ -30,7 +30,6 @@ import org.jspecify.annotations.Nullable;
|
|||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
@@ -170,15 +169,13 @@ class ImportsContextCustomizer implements ContextCustomizer {
|
|||||||
* {@link ImportSelector} that returns the original test class so that direct
|
* {@link ImportSelector} that returns the original test class so that direct
|
||||||
* {@code @Import} annotations are processed.
|
* {@code @Import} annotations are processed.
|
||||||
*/
|
*/
|
||||||
static class ImportsSelector implements ImportSelector, BeanFactoryAware {
|
static class ImportsSelector implements ImportSelector {
|
||||||
|
|
||||||
private static final String[] NO_IMPORTS = {};
|
private static final String[] NO_IMPORTS = {};
|
||||||
|
|
||||||
@SuppressWarnings("NullAway.Init")
|
private final ConfigurableListableBeanFactory beanFactory;
|
||||||
private ConfigurableListableBeanFactory beanFactory;
|
|
||||||
|
|
||||||
@Override
|
ImportsSelector(BeanFactory beanFactory) {
|
||||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
|
||||||
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
|
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-8
@@ -23,7 +23,6 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
|
||||||
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType;
|
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType;
|
||||||
import org.springframework.boot.context.annotation.ImportCandidates;
|
import org.springframework.boot.context.annotation.ImportCandidates;
|
||||||
@@ -51,9 +50,13 @@ import org.springframework.util.StringUtils;
|
|||||||
* @see ImportCandidates
|
* @see ImportCandidates
|
||||||
*/
|
*/
|
||||||
@Order(Ordered.LOWEST_PRECEDENCE)
|
@Order(Ordered.LOWEST_PRECEDENCE)
|
||||||
class ManagementContextConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware {
|
class ManagementContextConfigurationImportSelector implements DeferredImportSelector {
|
||||||
|
|
||||||
private @Nullable ClassLoader classLoader;
|
private final ClassLoader classLoader;
|
||||||
|
|
||||||
|
ManagementContextConfigurationImportSelector(ClassLoader classLoader) {
|
||||||
|
this.classLoader = classLoader;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] selectImports(AnnotationMetadata metadata) {
|
public String[] selectImports(AnnotationMetadata metadata) {
|
||||||
@@ -98,11 +101,6 @@ class ManagementContextConfigurationImportSelector implements DeferredImportSele
|
|||||||
return ImportCandidates.load(ManagementContextConfiguration.class, this.classLoader).getCandidates();
|
return ImportCandidates.load(ManagementContextConfiguration.class, this.classLoader).getCandidates();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
|
||||||
this.classLoader = classLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A management configuration class which can be sorted according to {@code @Order}.
|
* A management configuration class which can be sorted according to {@code @Order}.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+3
-1
@@ -64,7 +64,8 @@ class ManagementContextConfigurationImportSelectorTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void selectImportsLoadsFromResources() {
|
void selectImportsLoadsFromResources() {
|
||||||
String[] imports = new ManagementContextConfigurationImportSelector()
|
String[] imports = new ManagementContextConfigurationImportSelector(
|
||||||
|
ManagementContextConfigurationImportSelector.class.getClassLoader())
|
||||||
.selectImports(AnnotationMetadata.introspect(EnableChildContext.class));
|
.selectImports(AnnotationMetadata.introspect(EnableChildContext.class));
|
||||||
Set<String> expected = new HashSet<>();
|
Set<String> expected = new HashSet<>();
|
||||||
ImportCandidates
|
ImportCandidates
|
||||||
@@ -84,6 +85,7 @@ class ManagementContextConfigurationImportSelectorTests {
|
|||||||
private final List<String> factoryNames;
|
private final List<String> factoryNames;
|
||||||
|
|
||||||
private TestManagementContextConfigurationsImportSelector(Class<?>... classes) {
|
private TestManagementContextConfigurationsImportSelector(Class<?>... classes) {
|
||||||
|
super(ManagementContextConfigurationImportSelector.class.getClassLoader());
|
||||||
this.factoryNames = Stream.of(classes).map(Class::getName).toList();
|
this.factoryNames = Stream.of(classes).map(Class::getName).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-7
@@ -19,9 +19,7 @@ package org.springframework.boot.integration.autoconfigure;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
|
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
|
||||||
import org.springframework.core.annotation.AnnotationAttributes;
|
import org.springframework.core.annotation.AnnotationAttributes;
|
||||||
@@ -36,13 +34,11 @@ import org.springframework.integration.config.IntegrationComponentScanRegistrar;
|
|||||||
* @author Artem Bilan
|
* @author Artem Bilan
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
*/
|
*/
|
||||||
class IntegrationAutoConfigurationScanRegistrar extends IntegrationComponentScanRegistrar implements BeanFactoryAware {
|
class IntegrationAutoConfigurationScanRegistrar extends IntegrationComponentScanRegistrar {
|
||||||
|
|
||||||
@SuppressWarnings("NullAway.Init")
|
private final BeanFactory beanFactory;
|
||||||
private BeanFactory beanFactory;
|
|
||||||
|
|
||||||
@Override
|
IntegrationAutoConfigurationScanRegistrar(BeanFactory beanFactory) {
|
||||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
|
||||||
this.beanFactory = beanFactory;
|
this.beanFactory = beanFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-9
@@ -18,9 +18,7 @@ package org.springframework.boot.validation.autoconfigure;
|
|||||||
|
|
||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
@@ -42,20 +40,18 @@ import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
|||||||
* @author Matej Nedic
|
* @author Matej Nedic
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
*/
|
*/
|
||||||
class PrimaryDefaultValidatorPostProcessor implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
|
class PrimaryDefaultValidatorPostProcessor implements ImportBeanDefinitionRegistrar {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bean name of the auto-configured Validator.
|
* The bean name of the auto-configured Validator.
|
||||||
*/
|
*/
|
||||||
private static final String VALIDATOR_BEAN_NAME = "defaultValidator";
|
private static final String VALIDATOR_BEAN_NAME = "defaultValidator";
|
||||||
|
|
||||||
private @Nullable ConfigurableListableBeanFactory beanFactory;
|
private final @Nullable ConfigurableListableBeanFactory beanFactory;
|
||||||
|
|
||||||
@Override
|
PrimaryDefaultValidatorPostProcessor(BeanFactory beanFactory) {
|
||||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
this.beanFactory = (beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory)
|
||||||
if (beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory) {
|
? listableBeanFactory : null;
|
||||||
this.beanFactory = listableBeanFactory;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+5
-9
@@ -18,9 +18,7 @@ package org.springframework.boot.web.server.autoconfigure.reactive;
|
|||||||
|
|
||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
@@ -68,15 +66,13 @@ public class ReactiveWebServerConfiguration {
|
|||||||
* Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via
|
* Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via
|
||||||
* {@link ImportBeanDefinitionRegistrar} for early registration.
|
* {@link ImportBeanDefinitionRegistrar} for early registration.
|
||||||
*/
|
*/
|
||||||
static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
|
static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar {
|
||||||
|
|
||||||
private @Nullable ConfigurableListableBeanFactory beanFactory;
|
private final @Nullable ConfigurableListableBeanFactory beanFactory;
|
||||||
|
|
||||||
@Override
|
BeanPostProcessorsRegistrar(BeanFactory beanFactory) {
|
||||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
this.beanFactory = (beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory)
|
||||||
if (beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory) {
|
? listableBeanFactory : null;
|
||||||
this.beanFactory = listableBeanFactory;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+5
-9
@@ -19,9 +19,7 @@ package org.springframework.boot.web.server.autoconfigure.servlet;
|
|||||||
import jakarta.servlet.DispatcherType;
|
import jakarta.servlet.DispatcherType;
|
||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
@@ -86,15 +84,13 @@ public class ServletWebServerConfiguration {
|
|||||||
* Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via
|
* Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via
|
||||||
* {@link ImportBeanDefinitionRegistrar} for early registration.
|
* {@link ImportBeanDefinitionRegistrar} for early registration.
|
||||||
*/
|
*/
|
||||||
static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
|
static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar {
|
||||||
|
|
||||||
private @Nullable ConfigurableListableBeanFactory beanFactory;
|
private final @Nullable ConfigurableListableBeanFactory beanFactory;
|
||||||
|
|
||||||
@Override
|
BeanPostProcessorsRegistrar(BeanFactory beanFactory) {
|
||||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
this.beanFactory = (beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory)
|
||||||
if (beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory) {
|
? listableBeanFactory : null;
|
||||||
this.beanFactory = listableBeanFactory;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user