Skip to content

Commit

Permalink
Merge branch '3.0.x' into 3.1.x
Browse files Browse the repository at this point in the history
Closes gh-37635
  • Loading branch information
wilkinsona committed Sep 29, 2023
2 parents 385e627 + 458418b commit 1e4deed
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 26 deletions.
Expand Up @@ -19,10 +19,17 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.TypeReference;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution;
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor;
import org.springframework.beans.factory.aot.BeanFactoryInitializationCode;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
Expand All @@ -40,7 +47,8 @@
* @see ServletComponentScan
* @see ServletComponentScanRegistrar
*/
class ServletComponentRegisteringPostProcessor implements BeanFactoryPostProcessor, ApplicationContextAware {
class ServletComponentRegisteringPostProcessor
implements BeanFactoryPostProcessor, ApplicationContextAware, BeanFactoryInitializationAotProcessor {

private static final List<ServletComponentHandler> HANDLERS;

Expand Down Expand Up @@ -105,4 +113,29 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
this.applicationContext = applicationContext;
}

@Override
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
return new BeanFactoryInitializationAotContribution() {

@Override
public void applyTo(GenerationContext generationContext,
BeanFactoryInitializationCode beanFactoryInitializationCode) {
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
if (Objects.equals(definition.getBeanClassName(),
WebListenerHandler.ServletComponentWebListenerRegistrar.class.getName())) {
String listenerClassName = (String) definition.getConstructorArgumentValues()
.getArgumentValue(0, String.class)
.getValue();
generationContext.getRuntimeHints()
.reflection()
.registerType(TypeReference.of(listenerClassName),
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
}
}
}

};
}

}
Expand Up @@ -22,11 +22,9 @@
import java.util.Set;
import java.util.function.Supplier;

import org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
Expand Down Expand Up @@ -102,13 +100,4 @@ private void addPackageNames(Collection<String> additionalPackageNames) {

}

static class ServletComponentScanBeanRegistrationExcludeFilter implements BeanRegistrationExcludeFilter {

@Override
public boolean isExcludedFromAotProcessing(RegisteredBean registeredBean) {
return BEAN_NAME.equals(registeredBean.getBeanName());
}

}

}
Expand Up @@ -20,6 +20,3 @@ org.springframework.boot.jackson.JsonComponentModule.JsonComponentBeanFactoryIni
org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
org.springframework.boot.context.properties.ConfigurationPropertiesBeanRegistrationAotProcessor,\
org.springframework.boot.jackson.JsonMixinModuleEntriesBeanRegistrationAotProcessor

org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter=\
org.springframework.boot.web.servlet.ServletComponentScanRegistrar.ServletComponentScanBeanRegistrationExcludeFilter
Expand Up @@ -46,7 +46,10 @@
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.boot.web.servlet.testcomponents.TestMultipartServlet;
import org.springframework.boot.web.servlet.testcomponents.filter.TestFilter;
import org.springframework.boot.web.servlet.testcomponents.listener.TestListener;
import org.springframework.boot.web.servlet.testcomponents.servlet.TestMultipartServlet;
import org.springframework.boot.web.servlet.testcomponents.servlet.TestServlet;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
Expand Down Expand Up @@ -128,11 +131,9 @@ private void writeIndex(File temp) throws IOException {
File metaInf = new File(temp, "META-INF");
metaInf.mkdirs();
Properties index = new Properties();
index.setProperty("org.springframework.boot.web.servlet.testcomponents.TestFilter", WebFilter.class.getName());
index.setProperty("org.springframework.boot.web.servlet.testcomponents.TestListener",
WebListener.class.getName());
index.setProperty("org.springframework.boot.web.servlet.testcomponents.TestServlet",
WebServlet.class.getName());
index.setProperty(TestFilter.class.getName(), WebFilter.class.getName());
index.setProperty(TestListener.class.getName(), WebListener.class.getName());
index.setProperty(TestServlet.class.getName(), WebServlet.class.getName());
try (FileWriter writer = new FileWriter(new File(metaInf, "spring.components"))) {
index.store(writer, null);
}
Expand Down
Expand Up @@ -21,8 +21,12 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.aot.test.generate.TestGenerationContext;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.testcomponents.listener.TestListener;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
Expand Down Expand Up @@ -141,6 +145,19 @@ void processAheadOfTimeDoesNotRegisterServletComponentRegisteringPostProcessor()
});
}

@Test
void processAheadOfTimeRegistersReflectionHintsForWebListeners() {
AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext();
context.registerBean(ScanListenerPackage.class);
TestGenerationContext generationContext = new TestGenerationContext(
ClassName.get(getClass().getPackageName(), "TestTarget"));
new ApplicationContextAotGenerator().processAheadOfTime(context, generationContext);
assertThat(RuntimeHintsPredicates.reflection()
.onType(TestListener.class)
.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS))
.accepts(generationContext.getRuntimeHints());
}

@SuppressWarnings("unchecked")
private void compile(GenericApplicationContext context, Consumer<GenericApplicationContext> freshContext) {
TestGenerationContext generationContext = new TestGenerationContext(
Expand Down Expand Up @@ -192,4 +209,10 @@ static class NoBasePackages {

}

@Configuration(proxyBeanMethods = false)
@ServletComponentScan("org.springframework.boot.web.servlet.testcomponents.listener")
static class ScanListenerPackage {

}

}
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.springframework.boot.web.servlet.testcomponents;
package org.springframework.boot.web.servlet.testcomponents.filter;

import java.io.IOException;

Expand All @@ -27,7 +27,7 @@
import jakarta.servlet.annotation.WebFilter;

@WebFilter("/*")
class TestFilter implements Filter {
public class TestFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {
Expand Down
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.springframework.boot.web.servlet.testcomponents;
package org.springframework.boot.web.servlet.testcomponents.listener;

import java.io.IOException;
import java.util.EnumSet;
Expand Down
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.springframework.boot.web.servlet.testcomponents;
package org.springframework.boot.web.servlet.testcomponents.servlet;

import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
Expand Down
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.springframework.boot.web.servlet.testcomponents;
package org.springframework.boot.web.servlet.testcomponents.servlet;

import java.io.IOException;

Expand Down

0 comments on commit 1e4deed

Please sign in to comment.