Skip to content

Commit 229e984

Browse files
committed
Drop spring-boot-validation from spring-boot-actuator
Remove the validation dependency since it was only used for tests and we can wire things up directly instead. See gh-46357
1 parent 03161bc commit 229e984

File tree

3 files changed

+62
-20
lines changed

3 files changed

+62
-20
lines changed

module/spring-boot-actuator/build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ dependencies {
3030
optional(project(":module:spring-boot-health"))
3131
optional(project(":module:spring-boot-http-converter"))
3232
optional(project(":module:spring-boot-jsonb"))
33-
optional(project(":module:spring-boot-validation"))
3433
optional("com.github.ben-manes.caffeine:caffeine")
3534
optional("com.google.code.findbugs:jsr305")
3635
optional("com.zaxxer:HikariCP")

module/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererTests.java

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,30 @@
2121
import java.util.List;
2222
import java.util.function.Consumer;
2323

24+
import jakarta.validation.Validator;
2425
import org.junit.jupiter.api.Test;
2526

2627
import org.springframework.aot.hint.MemberCategory;
2728
import org.springframework.aot.hint.RuntimeHints;
2829
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
30+
import org.springframework.beans.factory.ObjectProvider;
31+
import org.springframework.beans.factory.config.BeanDefinition;
2932
import org.springframework.boot.actuate.endpoint.EndpointId;
3033
import org.springframework.boot.actuate.endpoint.annotation.DiscoveredEndpoint;
3134
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
3235
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
33-
import org.springframework.boot.autoconfigure.AutoConfigurations;
3436
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
3537
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
3638
import org.springframework.boot.test.context.runner.ContextConsumer;
37-
import org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration;
39+
import org.springframework.context.ApplicationContext;
40+
import org.springframework.context.annotation.Bean;
3841
import org.springframework.context.annotation.Configuration;
3942
import org.springframework.context.annotation.Import;
43+
import org.springframework.context.annotation.Role;
44+
import org.springframework.util.ClassUtils;
4045
import org.springframework.validation.annotation.Validated;
46+
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
47+
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
4148

4249
import static org.assertj.core.api.Assertions.assertThat;
4350
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
@@ -68,21 +75,22 @@ void getEndpointsShouldIncludeControllerEndpoints() {
6875
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
6976
assertThat(endpoint.getEndpointId()).isEqualTo(EndpointId.of("testcontroller"));
7077
assertThat(endpoint.getController()).isInstanceOf(TestControllerEndpoint.class);
78+
assertThat(ClassUtils.isCglibProxy(endpoint.getController())).isFalse();
7179
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
7280
}));
7381
}
7482

7583
@Test
7684
void getEndpointsShouldDiscoverProxyControllerEndpoints() {
77-
this.contextRunner.withUserConfiguration(TestProxyControllerEndpoint.class)
78-
.withConfiguration(AutoConfigurations.of(ValidationAutoConfiguration.class))
85+
this.contextRunner.withUserConfiguration(ProxyBeanConfiguration.class, TestProxyControllerEndpoint.class)
7986
.run(assertDiscoverer((discoverer) -> {
8087
Collection<ExposableControllerEndpoint> endpoints = discoverer.getEndpoints();
8188
assertThat(endpoints).hasSize(1);
8289
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
8390
assertThat(endpoint.getEndpointId()).isEqualTo(EndpointId.of("testcontroller"));
8491
assertThat(endpoint.getController()).isInstanceOf(TestProxyControllerEndpoint.class);
8592
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
93+
assertThat(ClassUtils.isCglibProxy(endpoint.getController())).isTrue();
8694
}));
8795
}
8896

@@ -95,19 +103,20 @@ void getEndpointsShouldIncludeRestControllerEndpoints() {
95103
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
96104
assertThat(endpoint.getEndpointId()).isEqualTo(EndpointId.of("testrestcontroller"));
97105
assertThat(endpoint.getController()).isInstanceOf(TestRestControllerEndpoint.class);
106+
assertThat(ClassUtils.isCglibProxy(endpoint.getController())).isFalse();
98107
}));
99108
}
100109

101110
@Test
102111
void getEndpointsShouldDiscoverProxyRestControllerEndpoints() {
103-
this.contextRunner.withUserConfiguration(TestProxyRestControllerEndpoint.class)
104-
.withConfiguration(AutoConfigurations.of(ValidationAutoConfiguration.class))
112+
this.contextRunner.withUserConfiguration(ProxyBeanConfiguration.class, TestProxyRestControllerEndpoint.class)
105113
.run(assertDiscoverer((discoverer) -> {
106114
Collection<ExposableControllerEndpoint> endpoints = discoverer.getEndpoints();
107115
assertThat(endpoints).hasSize(1);
108116
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
109117
assertThat(endpoint.getEndpointId()).isEqualTo(EndpointId.of("testrestcontroller"));
110118
assertThat(endpoint.getController()).isInstanceOf(TestProxyRestControllerEndpoint.class);
119+
assertThat(ClassUtils.isCglibProxy(endpoint.getController())).isTrue();
111120
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
112121
}));
113122
}
@@ -197,4 +206,22 @@ String read() {
197206

198207
}
199208

209+
static class ProxyBeanConfiguration {
210+
211+
@Bean
212+
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
213+
static LocalValidatorFactoryBean defaultValidator(ApplicationContext applicationContext) {
214+
return new LocalValidatorFactoryBean();
215+
}
216+
217+
@Bean
218+
static MethodValidationPostProcessor methodValidationPostProcessor(ObjectProvider<Validator> validator) {
219+
MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
220+
processor.setProxyTargetClass(true);
221+
processor.setValidatorProvider(validator);
222+
return processor;
223+
}
224+
225+
}
226+
200227
}

module/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererTests.java

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@
2727
import jakarta.servlet.ServletException;
2828
import jakarta.servlet.ServletRequest;
2929
import jakarta.servlet.ServletResponse;
30+
import jakarta.validation.ValidatorFactory;
31+
import org.assertj.core.extractor.Extractors;
3032
import org.jspecify.annotations.Nullable;
3133
import org.junit.jupiter.api.Test;
3234

35+
import org.springframework.aop.framework.ProxyFactory;
3336
import org.springframework.aot.hint.MemberCategory;
3437
import org.springframework.aot.hint.RuntimeHints;
3538
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
@@ -39,14 +42,15 @@
3942
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
4043
import org.springframework.boot.actuate.endpoint.web.EndpointServlet;
4144
import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint;
42-
import org.springframework.boot.autoconfigure.AutoConfigurations;
4345
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
4446
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
4547
import org.springframework.boot.test.context.runner.ContextConsumer;
46-
import org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration;
4748
import org.springframework.context.annotation.Configuration;
4849
import org.springframework.context.annotation.Import;
50+
import org.springframework.util.ClassUtils;
4951
import org.springframework.validation.annotation.Validated;
52+
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
53+
import org.springframework.validation.beanvalidation.MethodValidationInterceptor;
5054

5155
import static org.assertj.core.api.Assertions.assertThat;
5256
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
@@ -77,22 +81,24 @@ void getEndpointsShouldIncludeServletEndpoints() {
7781
ExposableServletEndpoint endpoint = endpoints.iterator().next();
7882
assertThat(endpoint.getEndpointId()).isEqualTo(EndpointId.of("testservlet"));
7983
assertThat(endpoint.getEndpointServlet()).isNotNull();
84+
Object servlet = Extractors.byName("servlet").apply(endpoint.getEndpointServlet());
85+
assertThat(ClassUtils.isCglibProxy(servlet)).isFalse();
8086
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
8187
}));
8288
}
8389

8490
@Test
8591
void getEndpointsShouldDiscoverProxyServletEndpoints() {
86-
this.contextRunner.withUserConfiguration(TestProxyServletEndpoint.class)
87-
.withConfiguration(AutoConfigurations.of(ValidationAutoConfiguration.class))
88-
.run(assertDiscoverer((discoverer) -> {
89-
Collection<ExposableServletEndpoint> endpoints = discoverer.getEndpoints();
90-
assertThat(endpoints).hasSize(1);
91-
ExposableServletEndpoint endpoint = endpoints.iterator().next();
92-
assertThat(endpoint.getEndpointId()).isEqualTo(EndpointId.of("testservlet"));
93-
assertThat(endpoint.getEndpointServlet()).isNotNull();
94-
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
95-
}));
92+
this.contextRunner.withUserConfiguration(TestProxyServletEndpoint.class).run(assertDiscoverer((discoverer) -> {
93+
Collection<ExposableServletEndpoint> endpoints = discoverer.getEndpoints();
94+
assertThat(endpoints).hasSize(1);
95+
ExposableServletEndpoint endpoint = endpoints.iterator().next();
96+
assertThat(endpoint.getEndpointId()).isEqualTo(EndpointId.of("testservlet"));
97+
assertThat(endpoint.getEndpointServlet()).isNotNull();
98+
Object servlet = Extractors.byName("servlet").apply(endpoint.getEndpointServlet());
99+
assertThat(ClassUtils.isCglibProxy(servlet)).isTrue();
100+
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
101+
}));
96102
}
97103

98104
@Test
@@ -179,7 +185,17 @@ static class TestProxyServletEndpoint implements Supplier<EndpointServlet> {
179185

180186
@Override
181187
public EndpointServlet get() {
182-
return new EndpointServlet(TestServlet.class);
188+
ValidatorFactory validator = new LocalValidatorFactoryBean();
189+
TestServlet target = new TestServlet();
190+
MethodValidationInterceptor interceptor = new MethodValidationInterceptor(validator);
191+
ProxyFactory proxyFactory = new ProxyFactory();
192+
proxyFactory.setTargetClass(EndpointServlet.class);
193+
proxyFactory.setTarget(target);
194+
proxyFactory.setProxyTargetClass(true);
195+
proxyFactory.addAdvice(interceptor);
196+
proxyFactory.getProxy();
197+
TestServlet servlet = (TestServlet) proxyFactory.getProxy();
198+
return new EndpointServlet(servlet);
183199
}
184200

185201
}

0 commit comments

Comments
 (0)