From e314e11985417ef4b5f2ce31025a8b05ab8ef482 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 13 Oct 2023 16:21:15 +0100 Subject: [PATCH] Fix AOT processing of @MultipartConfig annotated @WebServlet Closes gh-37637 --- .../boot/web/servlet/WebServletHandler.java | 10 +++++++--- .../ServletComponentScanRegistrarTests.java | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebServletHandler.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebServletHandler.java index 2a27c7961a3..40f2c06f740 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebServletHandler.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebServletHandler.java @@ -59,14 +59,18 @@ class WebServletHandler extends ServletComponentHandler { : beanDefinition.getBeanClassName()); } - private MultipartConfigElement determineMultipartConfig(AnnotatedBeanDefinition beanDefinition) { + private BeanDefinition determineMultipartConfig(AnnotatedBeanDefinition beanDefinition) { Map attributes = beanDefinition.getMetadata() .getAnnotationAttributes(MultipartConfig.class.getName()); if (attributes == null) { return null; } - return new MultipartConfigElement((String) attributes.get("location"), (Long) attributes.get("maxFileSize"), - (Long) attributes.get("maxRequestSize"), (Integer) attributes.get("fileSizeThreshold")); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(MultipartConfigElement.class); + builder.addConstructorArgValue(attributes.get("location")); + builder.addConstructorArgValue(attributes.get("maxFileSize")); + builder.addConstructorArgValue(attributes.get("maxRequestSize")); + builder.addConstructorArgValue(attributes.get("fileSizeThreshold")); + return builder.getBeanDefinition(); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java index c3525e49031..c829ac8e339 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java @@ -39,6 +39,7 @@ import org.springframework.javapoet.ClassName; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; /** * Tests for {@link ServletComponentScanRegistrar} @@ -158,6 +159,16 @@ class ServletComponentScanRegistrarTests { .accepts(generationContext.getRuntimeHints()); } + @Test + void processAheadOfTimeSucceedsForWebServletWithMultipartConfig() { + AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); + context.registerBean(ScanServletPackage.class); + TestGenerationContext generationContext = new TestGenerationContext( + ClassName.get(getClass().getPackageName(), "TestTarget")); + assertThatNoException() + .isThrownBy(() -> new ApplicationContextAotGenerator().processAheadOfTime(context, generationContext)); + } + @SuppressWarnings("unchecked") private void compile(GenericApplicationContext context, Consumer freshContext) { TestGenerationContext generationContext = new TestGenerationContext( @@ -215,4 +226,10 @@ class ServletComponentScanRegistrarTests { } + @Configuration(proxyBeanMethods = false) + @ServletComponentScan("org.springframework.boot.web.servlet.testcomponents.servlet") + static class ScanServletPackage { + + } + }