Reinstate support for legacy JSR-250 Resource annotation
This merges the existing support for the legacy JSR-250 PostConstruct/PreDestroy annotations into CommonAnnotationBeanPostProcessor itself, opening up the InitDestroyAnnotationBeanPostProcessor base class for multiple init/destroy methods in a single post-processor. This removes the need for a separate JSR-250 InitDestroyAnnotationBeanPostProcessor in AnnotationConfigUtils. Closes gh-30695
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user