Merge branch '6.0.x'

This commit is contained in:
Juergen Hoeller
2023-07-09 16:56:45 +02:00
9 changed files with 347 additions and 110 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@@ -207,10 +207,9 @@ public class ClassPathBeanDefinitionScannerTests {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.setIncludeAnnotationConfig(false);
scanner.scan("org.springframework.context.annotation3");
assertThatIllegalStateException().isThrownBy(() ->
scanner.scan(BASE_PACKAGE))
.withMessageContaining("stubFooDao")
.withMessageContaining(StubFooDao.class.getName());
assertThatIllegalStateException().isThrownBy(() -> scanner.scan(BASE_PACKAGE))
.withMessageContaining("stubFooDao")
.withMessageContaining(StubFooDao.class.getName());
}
@Test
@@ -267,11 +266,10 @@ public class ClassPathBeanDefinitionScannerTests {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.setIncludeAnnotationConfig(false);
scanner.scan("org.springframework.context.annotation2");
assertThatIllegalStateException().isThrownBy(() ->
scanner.scan(BASE_PACKAGE))
.withMessageContaining("myNamedDao")
.withMessageContaining(NamedStubDao.class.getName())
.withMessageContaining(NamedStubDao2.class.getName());
assertThatIllegalStateException().isThrownBy(() -> scanner.scan(BASE_PACKAGE))
.withMessageContaining("myNamedDao")
.withMessageContaining(NamedStubDao.class.getName())
.withMessageContaining(NamedStubDao2.class.getName());
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@@ -85,13 +85,33 @@ class ClassPathScanningCandidateComponentProviderTests {
ClassPathScanningCandidateComponentProviderTests.class.getClassLoader(),
new ClassPathResource("spring.components", NamedComponent.class));
private static final Set<Class<?>> springComponents = Set.of(
DefaultNamedComponent.class,
NamedComponent.class,
FooServiceImpl.class,
StubFooDao.class,
NamedStubDao.class,
ServiceInvocationCounter.class,
BarComponent.class
);
private static final Set<Class<?>> scannedJakartaComponents = Set.of(
JakartaNamedComponent.class,
JakartaManagedBeanComponent.class
);
private static final Set<Class<?>> indexedJakartaComponents = Set.of(
IndexedJakartaNamedComponent.class,
IndexedJakartaManagedBeanComponent.class
);
@Test
void defaultsWithScan() {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
provider.setResourceLoader(new DefaultResourceLoader(
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
testDefault(provider, true, false);
testDefault(provider, TEST_BASE_PACKAGE, true, false);
}
@Test
@@ -101,32 +121,9 @@ class ClassPathScanningCandidateComponentProviderTests {
testDefault(provider, "example", true, true);
}
private static final Set<Class<?>> springComponents = Set.of(
DefaultNamedComponent.class,
NamedComponent.class,
FooServiceImpl.class,
StubFooDao.class,
NamedStubDao.class,
ServiceInvocationCounter.class,
BarComponent.class
);
private void testDefault(ClassPathScanningCandidateComponentProvider provider, String basePackage,
boolean includeScannedJakartaComponents, boolean includeIndexedJakartaComponents) {
private static final Set<Class<?>> scannedJakartaComponents = Set.of(
JakartaNamedComponent.class,
JakartaManagedBeanComponent.class
);
private static final Set<Class<?>> indexedJakartaComponents = Set.of(
IndexedJakartaNamedComponent.class,
IndexedJakartaManagedBeanComponent.class
);
private void testDefault(ClassPathScanningCandidateComponentProvider provider, boolean includeScannedJakartaComponents, boolean includeIndexedJakartaComponents) {
testDefault(provider, TEST_BASE_PACKAGE, includeScannedJakartaComponents, includeIndexedJakartaComponents);
}
private void testDefault(ClassPathScanningCandidateComponentProvider provider, String basePackage, boolean includeScannedJakartaComponents, boolean includeIndexedJakartaComponents) {
Set<Class<?>> expectedTypes = new HashSet<>(springComponents);
if (includeScannedJakartaComponents) {
expectedTypes.addAll(scannedJakartaComponents);
@@ -205,7 +202,7 @@ class ClassPathScanningCandidateComponentProviderTests {
private void testCustomAnnotationTypeIncludeFilter(ClassPathScanningCandidateComponentProvider provider) {
provider.addIncludeFilter(new AnnotationTypeFilter(Component.class));
testDefault(provider, false, false);
testDefault(provider, TEST_BASE_PACKAGE, false, false);
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@@ -90,6 +90,18 @@ public class CommonAnnotationBeanPostProcessorTests {
assertThat(bean.destroyCalled).isTrue();
}
@Test
public void testPostConstructAndPreDestroyWithLegacyAnnotations() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(LegacyAnnotatedInitDestroyBean.class));
LegacyAnnotatedInitDestroyBean bean = (LegacyAnnotatedInitDestroyBean) bf.getBean("annotatedBean");
assertThat(bean.initCalled).isTrue();
bf.destroySingletons();
assertThat(bean.destroyCalled).isTrue();
}
@Test
public void testPostConstructAndPreDestroyWithManualConfiguration() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -200,6 +212,30 @@ public class CommonAnnotationBeanPostProcessorTests {
assertThat(bean.destroy3Called).isTrue();
}
@Test
public void testResourceInjectionWithLegacyAnnotations() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor();
bpp.setResourceFactory(bf);
bf.addBeanPostProcessor(bpp);
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(LegacyResourceInjectionBean.class));
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
TestBean tb2 = new TestBean();
bf.registerSingleton("testBean2", tb2);
LegacyResourceInjectionBean bean = (LegacyResourceInjectionBean) bf.getBean("annotatedBean");
assertThat(bean.initCalled).isTrue();
assertThat(bean.init2Called).isTrue();
assertThat(bean.init3Called).isTrue();
assertThat(bean.getTestBean()).isSameAs(tb);
assertThat(bean.getTestBean2()).isSameAs(tb2);
bf.destroySingletons();
assertThat(bean.destroyCalled).isTrue();
assertThat(bean.destroy2Called).isTrue();
assertThat(bean.destroy3Called).isTrue();
}
@Test
public void testResourceInjectionWithResolvableDependencyType() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -532,6 +568,30 @@ public class CommonAnnotationBeanPostProcessorTests {
}
public static class LegacyAnnotatedInitDestroyBean {
public boolean initCalled = false;
public boolean destroyCalled = false;
@javax.annotation.PostConstruct
private void init() {
if (this.initCalled) {
throw new IllegalStateException("Already called");
}
this.initCalled = true;
}
@javax.annotation.PreDestroy
private void destroy() {
if (this.destroyCalled) {
throw new IllegalStateException("Already called");
}
this.destroyCalled = true;
}
}
public static class InitDestroyBeanPostProcessor implements DestructionAwareBeanPostProcessor {
@Override
@@ -641,6 +701,83 @@ public class CommonAnnotationBeanPostProcessorTests {
}
public static class LegacyResourceInjectionBean extends LegacyAnnotatedInitDestroyBean {
public boolean init2Called = false;
public boolean init3Called = false;
public boolean destroy2Called = false;
public boolean destroy3Called = false;
@javax.annotation.Resource
private TestBean testBean;
private TestBean testBean2;
@javax.annotation.PostConstruct
protected void init2() {
if (this.testBean == null || this.testBean2 == null) {
throw new IllegalStateException("Resources not injected");
}
if (!this.initCalled) {
throw new IllegalStateException("Superclass init method not called yet");
}
if (this.init2Called) {
throw new IllegalStateException("Already called");
}
this.init2Called = true;
}
@javax.annotation.PostConstruct
private void init() {
if (this.init3Called) {
throw new IllegalStateException("Already called");
}
this.init3Called = true;
}
@javax.annotation.PreDestroy
protected void destroy2() {
if (this.destroyCalled) {
throw new IllegalStateException("Superclass destroy called too soon");
}
if (this.destroy2Called) {
throw new IllegalStateException("Already called");
}
this.destroy2Called = true;
}
@javax.annotation.PreDestroy
private void destroy() {
if (this.destroyCalled) {
throw new IllegalStateException("Superclass destroy called too soon");
}
if (this.destroy3Called) {
throw new IllegalStateException("Already called");
}
this.destroy3Called = true;
}
@javax.annotation.Resource
public void setTestBean2(TestBean testBean2) {
if (this.testBean2 != null) {
throw new IllegalStateException("Already called");
}
this.testBean2 = testBean2;
}
public TestBean getTestBean() {
return testBean;
}
public TestBean getTestBean2() {
return testBean2;
}
}
static class NonPublicResourceInjectionBean<B> extends ResourceInjectionBean {
@Resource(name="testBean4", type=TestBean.class)

View File

@@ -27,7 +27,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.aot.test.generate.TestGenerationContext;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContextInitializer;
@@ -254,18 +253,11 @@ class InitDestroyMethodLifecycleTests {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
// Configure and register an InitDestroyAnnotationBeanPostProcessor as
// done in AnnotationConfigUtils.registerAnnotationConfigProcessors()
// for an ApplicatonContext.
InitDestroyAnnotationBeanPostProcessor initDestroyBpp = new InitDestroyAnnotationBeanPostProcessor();
initDestroyBpp.setInitAnnotationType(javax.annotation.PostConstruct.class);
initDestroyBpp.setDestroyAnnotationType(javax.annotation.PreDestroy.class);
beanFactory.addBeanPostProcessor(initDestroyBpp);
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
beanDefinition.setInitMethodName(initMethodName);
beanDefinition.setDestroyMethodName(destroyMethodName);
beanFactory.registerBeanDefinition("lifecycleTestBean", beanDefinition);
return beanFactory;
}
@@ -275,6 +267,7 @@ class InitDestroyMethodLifecycleTests {
GenericApplicationContext context = new GenericApplicationContext();
initializer.initialize(context);
context.refresh();
return context;
}
@@ -309,6 +302,7 @@ class InitDestroyMethodLifecycleTests {
}
}
static class CustomInitDestroyBean {
final List<String> initMethods = new ArrayList<>();
@@ -323,6 +317,7 @@ class InitDestroyMethodLifecycleTests {
}
}
static class CustomAnnotatedPrivateInitDestroyBean extends CustomInitializingDisposableBean {
@PostConstruct
@@ -336,6 +331,7 @@ class InitDestroyMethodLifecycleTests {
}
}
static class CustomAnnotatedPrivateSameNameInitDestroyBean extends CustomAnnotatedPrivateInitDestroyBean {
@PostConstruct
@@ -351,6 +347,7 @@ class InitDestroyMethodLifecycleTests {
}
}
static class CustomInitializingDisposableBean extends CustomInitDestroyBean
implements InitializingBean, DisposableBean {
@@ -365,6 +362,7 @@ class InitDestroyMethodLifecycleTests {
}
}
static class CustomAnnotatedInitDestroyBean extends CustomInitializingDisposableBean {
@PostConstruct
@@ -378,6 +376,7 @@ class InitDestroyMethodLifecycleTests {
}
}
static class CustomAnnotatedInitDestroyWithShadowedMethodsBean extends CustomInitializingDisposableBean {
@PostConstruct
@@ -393,6 +392,7 @@ class InitDestroyMethodLifecycleTests {
}
}
static class AllInOneBean implements InitializingBean, DisposableBean {
final List<String> initMethods = new ArrayList<>();
@@ -411,8 +411,9 @@ class InitDestroyMethodLifecycleTests {
}
}
static class SubPackagePrivateInitDestroyBean extends PackagePrivateInitDestroyBean
implements InitializingBean, DisposableBean {
implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() {
@@ -433,7 +434,6 @@ class InitDestroyMethodLifecycleTests {
void preDestroy() {
this.destroyMethods.add("SubPackagePrivateInitDestroyBean.preDestroy");
}
}
}