Skip to content

Prevent @Bean method being public if it should not be #45891

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ static List<ArchRule> standard() {
rules.add(methodLevelConfigurationPropertiesShouldNotSpecifyOnlyPrefixAttribute());
rules.add(conditionsShouldNotBePublic());
rules.add(allConfigurationPropertiesBindingBeanMethodsShouldBeStatic());
rules.add(allConfigurationMethodsShouldNotBePublicIfReturnTypeOrParameterTypeIsNotPublic());
return List.copyOf(rules);
}

Expand Down Expand Up @@ -319,6 +320,30 @@ private static ArchRule allConfigurationPropertiesBindingBeanMethodsShouldBeStat
.allowEmptyShould(true);
}

private static ArchRule allConfigurationMethodsShouldNotBePublicIfReturnTypeOrParameterTypeIsNotPublic() {
return methodsThatAreAnnotatedWith("org.springframework.context.annotation.Bean")
.should(check("not be public if return type is not public or any of parameter types is not public",
ArchitectureRules::configurationMethodsShouldNotBePublicIfReturnTypeOrParameterTypeIsNotPublic))
.allowEmptyShould(true);
}

private static void configurationMethodsShouldNotBePublicIfReturnTypeOrParameterTypeIsNotPublic(JavaMethod item,
ConditionEvents events) {
if (!item.getModifiers().contains(JavaModifier.PUBLIC)) {
return;
}
boolean violated = !item.getReturnType().toErasure().getModifiers().contains(JavaModifier.PUBLIC);
if (!violated) {
violated = item.getParameterTypes()
.stream()
.anyMatch((parameterType) -> !parameterType.toErasure().getModifiers().contains(JavaModifier.PUBLIC));
}
if (violated) {
addViolation(events, item, item.getDescription()
+ " should not be public if return type is not public or any of parameter types is not public");
}
}

private static boolean containsOnlySingleType(JavaType[] types, JavaType type) {
return types.length == 1 && type.equals(types[0]);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 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.
Expand Down Expand Up @@ -59,7 +59,7 @@ public ReadinessStateHealthIndicator readinessStateHealthIndicator(
}

@Bean
public AvailabilityProbesHealthEndpointGroupsPostProcessor availabilityProbesHealthEndpointGroupsPostProcessor(
AvailabilityProbesHealthEndpointGroupsPostProcessor availabilityProbesHealthEndpointGroupsPostProcessor(
Environment environment) {
return new AvailabilityProbesHealthEndpointGroupsPostProcessor(environment);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public CloudFoundryInfoEndpointWebExtension cloudFoundryInfoEndpointWebExtension

@Bean
@SuppressWarnings("removal")
public CloudFoundryWebFluxEndpointHandlerMapping cloudFoundryWebFluxEndpointHandlerMapping(
CloudFoundryWebFluxEndpointHandlerMapping cloudFoundryWebFluxEndpointHandlerMapping(
ParameterValueMapper parameterMapper, EndpointMediaTypes endpointMediaTypes,
WebClient.Builder webClientBuilder,
org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier controllerEndpointsSupplier,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public CloudFoundryInfoEndpointWebExtension cloudFoundryInfoEndpointWebExtension

@Bean
@SuppressWarnings("removal")
public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServletHandlerMapping(
CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServletHandlerMapping(
ParameterValueMapper parameterMapper, EndpointMediaTypes endpointMediaTypes,
RestTemplateBuilder restTemplateBuilder,
org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier servletEndpointsSupplier,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public JmxEndpointDiscoverer jmxAnnotationEndpointDiscoverer(ParameterValueMappe

@Bean
@ConditionalOnMissingBean(value = EndpointObjectNameFactory.class, search = SearchStrategy.CURRENT)
public DefaultEndpointObjectNameFactory endpointObjectNameFactory(MBeanServer mBeanServer) {
DefaultEndpointObjectNameFactory endpointObjectNameFactory(MBeanServer mBeanServer) {
String contextId = ObjectUtils.getIdentityHexString(this.applicationContext);
return new DefaultEndpointObjectNameFactory(this.properties, this.jmxProperties, mBeanServer, contextId);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2025 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.
Expand Down Expand Up @@ -56,7 +56,7 @@ public Clock micrometerClock() {
}

@Bean
public static MeterRegistryPostProcessor meterRegistryPostProcessor(ApplicationContext applicationContext,
static MeterRegistryPostProcessor meterRegistryPostProcessor(ApplicationContext applicationContext,
ObjectProvider<MetricsProperties> metricsProperties,
ObjectProvider<MeterRegistryCustomizer<?>> meterRegistryCustomizers,
ObjectProvider<MeterFilter> meterFilters, ObjectProvider<MeterBinder> meterBinders) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2025 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.
Expand Down Expand Up @@ -44,7 +44,7 @@
public class RabbitMetricsAutoConfiguration {

@Bean
public static RabbitConnectionFactoryMetricsPostProcessor rabbitConnectionFactoryMetricsPostProcessor(
static RabbitConnectionFactoryMetricsPostProcessor rabbitConnectionFactoryMetricsPostProcessor(
ApplicationContext applicationContext) {
return new RabbitConnectionFactoryMetricsPostProcessor(applicationContext);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public MetricsRepositoryMethodInvocationListener metricsRepositoryMethodInvocati
}

@Bean
public static MetricsRepositoryMethodInvocationListenerBeanPostProcessor metricsRepositoryMethodInvocationListenerBeanPostProcessor(
static MetricsRepositoryMethodInvocationListenerBeanPostProcessor metricsRepositoryMethodInvocationListenerBeanPostProcessor(
ObjectProvider<MetricsRepositoryMethodInvocationListener> metricsRepositoryMethodInvocationListener) {
return new MetricsRepositoryMethodInvocationListenerBeanPostProcessor(
SingletonSupplier.of(metricsRepositoryMethodInvocationListener::getObject));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 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.
Expand Down Expand Up @@ -725,7 +725,7 @@ private void load(Consumer<T> contextCustomizer, String endpointPath,
protected static class TestEndpointConfiguration {

@Bean
public TestEndpoint testEndpoint(EndpointDelegate endpointDelegate) {
TestEndpoint testEndpoint(EndpointDelegate endpointDelegate) {
return new TestEndpoint(endpointDelegate);
}

Expand Down Expand Up @@ -846,7 +846,7 @@ NullDeleteResponseEndpoint nullDeleteResponseEndpoint() {
protected static class ResourceEndpointConfiguration {

@Bean
public ResourceEndpoint resourceEndpoint() {
ResourceEndpoint resourceEndpoint() {
return new ResourceEndpoint();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public CacheManagerCustomizers cacheManagerCustomizers(ObjectProvider<CacheManag
}

@Bean
public CacheManagerValidator cacheAutoConfigurationValidator(CacheProperties cacheProperties,
CacheManagerValidator cacheAutoConfigurationValidator(CacheProperties cacheProperties,
ObjectProvider<CacheManager> cacheManager) {
return new CacheManagerValidator(cacheProperties, cacheManager);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
public class RepositoryRestMvcAutoConfiguration {

@Bean
public SpringBootRepositoryRestConfigurer springBootRepositoryRestConfigurer(
SpringBootRepositoryRestConfigurer springBootRepositoryRestConfigurer(
ObjectProvider<Jackson2ObjectMapperBuilder> objectMapperBuilder, RepositoryRestProperties properties) {
return new SpringBootRepositoryRestConfigurer(objectMapperBuilder.getIfAvailable(), properties);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ public class FlywayAutoConfiguration {

@Bean
@ConfigurationPropertiesBinding
public static StringOrNumberToMigrationVersionConverter stringOrNumberMigrationVersionConverter() {
static StringOrNumberToMigrationVersionConverter stringOrNumberMigrationVersionConverter() {
return new StringOrNumberToMigrationVersionConverter();
}

@Bean
public FlywaySchemaManagementProvider flywayDefaultDdlModeProvider(ObjectProvider<Flyway> flyways) {
FlywaySchemaManagementProvider flywayDefaultDdlModeProvider(ObjectProvider<Flyway> flyways) {
return new FlywaySchemaManagementProvider(flyways);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public GraphQlRSocketHandler graphQlRSocketHandler(ExecutionGraphQlService graph

@Bean
@ConditionalOnMissingBean
public GraphQlRSocketController graphQlRSocketController(GraphQlRSocketHandler handler) {
GraphQlRSocketController graphQlRSocketController(GraphQlRSocketHandler handler) {
return new GraphQlRSocketController(handler);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public Gson gson(GsonBuilder gsonBuilder) {
}

@Bean
public StandardGsonBuilderCustomizer standardGsonBuilderCustomizer(GsonProperties gsonProperties) {
StandardGsonBuilderCustomizer standardGsonBuilderCustomizer(GsonProperties gsonProperties) {
return new StandardGsonBuilderCustomizer(gsonProperties);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@
public class LiquibaseAutoConfiguration {

@Bean
public LiquibaseSchemaManagementProvider liquibaseDefaultDdlModeProvider(
ObjectProvider<SpringLiquibase> liquibases) {
LiquibaseSchemaManagementProvider liquibaseDefaultDdlModeProvider(ObjectProvider<SpringLiquibase> liquibases) {
return new LiquibaseSchemaManagementProvider(liquibases);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public CharacterEncodingFilter characterEncodingFilter() {
}

@Bean
public LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
return new LocaleCharsetMappingsCustomizer(this.properties);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer,

private ServletContext servletContext;

public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties,
WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties,
ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
ObjectProvider<DispatcherServletPath> dispatcherServletPath,
Expand Down Expand Up @@ -383,7 +383,7 @@ public static RequestContextFilter requestContextFilter() {
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WebProperties.class)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {

private final Resources resourceProperties;

Expand All @@ -397,7 +397,7 @@ public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfigurat

private ResourceLoader resourceLoader;

public EnableWebMvcConfiguration(WebMvcProperties mvcProperties, WebProperties webProperties,
EnableWebMvcConfiguration(WebMvcProperties mvcProperties, WebProperties webProperties,
ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider,
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
ListableBeanFactory beanFactory) {
Expand All @@ -420,14 +420,14 @@ protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
}

@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
return createWelcomePageHandlerMapping(applicationContext, mvcConversionService, mvcResourceUrlProvider,
WelcomePageHandlerMapping::new);
}

@Bean
public WelcomePageNotAcceptableHandlerMapping welcomePageNotAcceptableHandlerMapping(
WelcomePageNotAcceptableHandlerMapping welcomePageNotAcceptableHandlerMapping(
ApplicationContext applicationContext, FormattingConversionService mvcConversionService,
ResourceUrlProvider mvcResourceUrlProvider) {
return createWelcomePageHandlerMapping(applicationContext, mvcConversionService, mvcResourceUrlProvider,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ public BasicErrorController basicErrorController(ErrorAttributes errorAttributes
}

@Bean
public ErrorPageCustomizer errorPageCustomizer(DispatcherServletPath dispatcherServletPath) {
ErrorPageCustomizer errorPageCustomizer(DispatcherServletPath dispatcherServletPath) {
return new ErrorPageCustomizer(this.serverProperties, dispatcherServletPath);
}

@Bean
public static PreserveErrorControllerTargetClassPostProcessor preserveErrorControllerTargetClassPostProcessor() {
static PreserveErrorControllerTargetClassPostProcessor preserveErrorControllerTargetClassPostProcessor() {
return new PreserveErrorControllerTargetClassPostProcessor();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 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.
Expand Down Expand Up @@ -84,7 +84,7 @@ public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServle
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Conditional(OnWsdlLocationsCondition.class)
public static WsdlDefinitionBeanFactoryPostProcessor wsdlDefinitionBeanFactoryPostProcessor() {
static WsdlDefinitionBeanFactoryPostProcessor wsdlDefinitionBeanFactoryPostProcessor() {
return new WsdlDefinitionBeanFactoryPostProcessor();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 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.
Expand Down Expand Up @@ -29,12 +29,12 @@
public class ScannedFactoryBeanWithBeanMethodArgumentsConfiguration {

@Bean
public Foo foo() {
Foo foo() {
return new Foo();
}

@Bean
public ScanFactoryBean exampleBeanFactoryBean(Foo foo) {
ScanFactoryBean exampleBeanFactoryBean(Foo foo) {
return new ScanFactoryBean("foo");
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2025 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.
Expand Down Expand Up @@ -77,15 +77,15 @@ public String message() {
static class TestConfiguration {

@Configuration(proxyBeanMethods = false)
public class JerseyConfiguration {
static class JerseyConfiguration {

@Bean
public TestApplication testApplication() {
TestApplication testApplication() {
return new TestApplication();
}

@Bean
public ResourceConfig conf(TestApplication app) {
ResourceConfig conf(TestApplication app) {
ResourceConfig config = ResourceConfig.forApplication(app);
config.register(TestController.class);
return config;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 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.
Expand Down Expand Up @@ -142,7 +142,7 @@ void sslBundleWithoutClassPathPrefix() {
public static class CustomSslBundleConfiguration {

@Bean
public SslBundleRegistrar customSslBundlesRegistrar(CustomSslProperties properties) {
SslBundleRegistrar customSslBundlesRegistrar(CustomSslProperties properties) {
return new CustomSslBundlesRegistrar(properties);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2025 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.
Expand All @@ -24,7 +24,7 @@
public class MyMeterBinderConfiguration {

@Bean
public MeterBinder queueSize(Queue queue) {
MeterBinder queueSize(Queue queue) {
return (registry) -> Gauge.builder("queueSize", queue::size).register(registry);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2025 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.
Expand Down Expand Up @@ -34,7 +34,7 @@ public static class SomeServiceConfiguration {

@Bean
@ConditionalOnMissingBean
public SomeService someService() {
SomeService someService() {
return new SomeService();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class ThirdPartyConfiguration {

@Bean
@ConfigurationProperties("another")
public AnotherComponent anotherComponent() {
AnotherComponent anotherComponent() {
return new AnotherComponent();
}

Expand Down
Loading