General upgrade to Jakarta EE 11 APIs

Includes removal of ManagedBean and javax.annotation legacy support.
Includes AbstractJson(Http)MessageConverter revision for Yasson 3.0.
Includes initial Hibernate ORM 7.0 upgrade.

Closes gh-34011
Closes gh-33750
This commit is contained in:
Juergen Hoeller
2024-12-03 13:30:25 +01:00
parent 15c6d3449b
commit 949432ce8b
65 changed files with 200 additions and 2995 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -51,11 +51,8 @@ import org.springframework.util.StringUtils;
* {@link org.springframework.stereotype.Repository @Repository}) are
* themselves annotated with {@code @Component}.
*
* <p>Also supports Jakarta EE's {@link jakarta.annotation.ManagedBean} and
* JSR-330's {@link jakarta.inject.Named} annotations (as well as their pre-Jakarta
* {@code javax.annotation.ManagedBean} and {@code javax.inject.Named} equivalents),
* if available. Note that Spring component annotations always override such
* standard annotations.
* <p>Also supports JSR-330's {@link jakarta.inject.Named} annotation if available.
* Note that Spring component annotations always override such standard annotations.
*
* <p>If the annotation's value doesn't indicate a bean name, an appropriate
* name will be built based on the short name of the class (with the first
@@ -219,10 +216,7 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator {
Set<String> metaAnnotationTypes, Map<String, Object> attributes) {
boolean isStereotype = metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME) ||
annotationType.equals("jakarta.annotation.ManagedBean") ||
annotationType.equals("javax.annotation.ManagedBean") ||
annotationType.equals("jakarta.inject.Named") ||
annotationType.equals("javax.inject.Named");
annotationType.equals("jakarta.inject.Named");
return (isStereotype && attributes.containsKey("value"));
}

View File

@@ -117,9 +117,6 @@ public abstract class AnnotationConfigUtils {
private static final boolean jakartaAnnotationsPresent =
ClassUtils.isPresent("jakarta.annotation.PostConstruct", classLoader);
private static final boolean jsr250Present =
ClassUtils.isPresent("javax.annotation.PostConstruct", classLoader);
private static final boolean jpaPresent =
ClassUtils.isPresent("jakarta.persistence.EntityManagerFactory", classLoader) &&
ClassUtils.isPresent(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, classLoader);
@@ -169,8 +166,7 @@ public abstract class AnnotationConfigUtils {
}
// Check for Jakarta Annotations support, and if present add the CommonAnnotationBeanPostProcessor.
if ((jakartaAnnotationsPresent || jsr250Present) &&
!registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
if (jakartaAnnotationsPresent && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -48,8 +48,7 @@ import org.springframework.util.PatternMatchUtils;
* {@link org.springframework.stereotype.Service @Service}, or
* {@link org.springframework.stereotype.Controller @Controller} stereotype.
*
* <p>Also supports Jakarta EE's {@link jakarta.annotation.ManagedBean} and
* JSR-330's {@link jakarta.inject.Named} annotations, if available.
* <p>Also supports JSR-330's {@link jakarta.inject.Named} annotations, if available.
*
* @author Mark Fisher
* @author Juergen Hoeller

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -216,31 +216,12 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
* {@link Component @Component} meta-annotation including the
* {@link Repository @Repository}, {@link Service @Service}, and
* {@link Controller @Controller} stereotype annotations.
* <p>Also supports Jakarta EE's {@link jakarta.annotation.ManagedBean} and
* JSR-330's {@link jakarta.inject.Named} annotations (as well as their
* pre-Jakarta {@code javax.annotation.ManagedBean} and {@code javax.inject.Named}
* equivalents), if available.
* <p>Also supports JSR-330's {@link jakarta.inject.Named} annotation if available.
*/
@SuppressWarnings("unchecked")
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("jakarta.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'jakarta.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Jakarta EE) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("jakarta.inject.Named", cl)), false));
@@ -249,14 +230,6 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
catch (ClassNotFoundException ex) {
// JSR-330 API (as included in Jakarta EE) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
/**

View File

@@ -96,11 +96,6 @@ import org.springframework.util.StringValueResolver;
* and default names as well. The target beans can be simple POJOs, with no special
* requirements other than the type having to match.
*
* <p>Additionally, the original {@code javax.annotation} variants of the annotations
* dating back to the JSR-250 specification (Java EE 5-8, also included in JDK 6-8)
* are still supported as well. Note that this is primarily for a smooth upgrade path,
* not for adoption in new applications.
*
* <p>This post-processor also supports the EJB {@link jakarta.ejb.EJB} annotation,
* analogous to {@link jakarta.annotation.Resource}, with the capability to
* specify both a local bean name and a global JNDI name for fallback retrieval.
@@ -154,9 +149,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
@Nullable
private static final Class<? extends Annotation> jakartaResourceType;
@Nullable
private static final Class<? extends Annotation> javaxResourceType;
@Nullable
private static final Class<? extends Annotation> ejbAnnotationType;
@@ -166,11 +158,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
resourceAnnotationTypes.add(jakartaResourceType);
}
javaxResourceType = loadAnnotationType("javax.annotation.Resource");
if (javaxResourceType != null) {
resourceAnnotationTypes.add(javaxResourceType);
}
ejbAnnotationType = loadAnnotationType("jakarta.ejb.EJB");
if (ejbAnnotationType != null) {
resourceAnnotationTypes.add(ejbAnnotationType);
@@ -212,10 +199,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
addInitAnnotationType(loadAnnotationType("jakarta.annotation.PostConstruct"));
addDestroyAnnotationType(loadAnnotationType("jakarta.annotation.PreDestroy"));
// Tolerate legacy JSR-250 annotations in javax.annotation package
addInitAnnotationType(loadAnnotationType("javax.annotation.PostConstruct"));
addDestroyAnnotationType(loadAnnotationType("javax.annotation.PreDestroy"));
// java.naming module present on JDK 9+?
if (jndiPresent) {
this.jndiFactory = new SimpleJndiBeanFactory();
@@ -444,14 +427,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
currElements.add(new ResourceElement(field, field, null));
}
}
else if (javaxResourceType != null && field.isAnnotationPresent(javaxResourceType)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static fields");
}
if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
currElements.add(new LegacyResourceElement(field, field, null));
}
}
});
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
@@ -486,21 +461,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
}
}
else if (javaxResourceType != null && bridgedMethod.isAnnotationPresent(javaxResourceType)) {
if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static methods");
}
Class<?>[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 1) {
throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
}
if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new LegacyResourceElement(method, bridgedMethod, pd));
}
}
}
});
elements.addAll(0, currElements);
@@ -746,57 +706,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
/**
* Class representing injection information about an annotated field
* or setter method, supporting the @Resource annotation.
*/
private class LegacyResourceElement extends LookupElement {
private final boolean lazyLookup;
public LegacyResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
super(member, pd);
javax.annotation.Resource resource = ae.getAnnotation(javax.annotation.Resource.class);
String resourceName = resource.name();
Class<?> resourceType = resource.type();
this.isDefaultName = !StringUtils.hasLength(resourceName);
if (this.isDefaultName) {
resourceName = this.member.getName();
if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
resourceName = StringUtils.uncapitalizeAsProperty(resourceName.substring(3));
}
}
else if (embeddedValueResolver != null) {
resourceName = embeddedValueResolver.resolveStringValue(resourceName);
}
if (Object.class != resourceType) {
checkResourceType(resourceType);
}
else {
// No resource type specified... check field/method.
resourceType = getResourceType();
}
this.name = (resourceName != null ? resourceName : "");
this.lookupType = resourceType;
String lookupValue = resource.lookup();
this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());
Lazy lazy = ae.getAnnotation(Lazy.class);
this.lazyLookup = (lazy != null && lazy.value());
}
@Override
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
getResource(this, requestingBeanName));
}
@Override
boolean isLazyLookup() {
return this.lazyLookup;
}
}
/**
* Class representing injection information about an annotated field
* or setter method, supporting the @EJB annotation.

View File

@@ -1,24 +0,0 @@
/*
* Copyright 2002-2022 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.indexed;
/**
* @author Sam Brannen
*/
@jakarta.annotation.ManagedBean
public class IndexedJakartaManagedBeanComponent {
}

View File

@@ -1,24 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.indexed;
/**
* @author Sam Brannen
*/
@javax.annotation.ManagedBean
public class IndexedJavaxManagedBeanComponent {
}

View File

@@ -1,24 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.indexed;
/**
* @author Sam Brannen
*/
@javax.inject.Named("myIndexedJavaxNamedComponent")
public class IndexedJavaxNamedComponent {
}

View File

@@ -1,24 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.scannable;
/**
* @author Sam Brannen
*/
@jakarta.annotation.ManagedBean("myJakartaManagedBeanComponent")
public class JakartaManagedBeanComponent {
}

View File

@@ -1,24 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.scannable;
/**
* @author Sam Brannen
*/
@javax.annotation.ManagedBean("myJavaxManagedBeanComponent")
public class JavaxManagedBeanComponent {
}

View File

@@ -1,24 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.scannable;
/**
* @author Sam Brannen
*/
@javax.inject.Named("myJavaxNamedComponent")
public class JavaxNamedComponent {
}

View File

@@ -40,8 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Integration tests for handling JSR-330 {@link jakarta.inject.Qualifier} and
* {@link javax.inject.Qualifier} annotations.
* Integration tests for handling {@link jakarta.inject.Qualifier} annotations.
*
* @author Juergen Hoeller
* @author Sam Brannen
@@ -317,16 +316,6 @@ class InjectAnnotationAutowireContextTests {
assertThat(bean.getAnimal2().getName()).isEqualTo("Jakarta Fido");
}
@Test // gh-33345
void autowiredConstructorArgumentResolvesJavaxNamedCandidate() {
Class<JavaxNamedConstructorArgumentTestBean> testBeanClass = JavaxNamedConstructorArgumentTestBean.class;
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(testBeanClass, JavaxCat.class, JavaxDog.class);
JavaxNamedConstructorArgumentTestBean bean = context.getBean(testBeanClass);
assertThat(bean.getAnimal1().getName()).isEqualTo("Javax Tiger");
assertThat(bean.getAnimal2().getName()).isEqualTo("Javax Fido");
}
@Test
void autowiredFieldResolvesQualifiedCandidateWithDefaultValueAndNoValueOnBeanDefinition() {
GenericApplicationContext context = new GenericApplicationContext();
@@ -587,29 +576,6 @@ class InjectAnnotationAutowireContextTests {
}
static class JavaxNamedConstructorArgumentTestBean {
private final Animal animal1;
private final Animal animal2;
@javax.inject.Inject
public JavaxNamedConstructorArgumentTestBean(@javax.inject.Named("Cat") Animal animal1,
@javax.inject.Named("Dog") Animal animal2) {
this.animal1 = animal1;
this.animal2 = animal2;
}
public Animal getAnimal1() {
return this.animal1;
}
public Animal getAnimal2() {
return this.animal2;
}
}
public static class QualifiedFieldWithDefaultValueTestBean {
@Inject
@@ -705,16 +671,6 @@ class InjectAnnotationAutowireContextTests {
}
@javax.inject.Named("Cat")
static class JavaxCat implements Animal {
@Override
public String getName() {
return "Javax Tiger";
}
}
@jakarta.inject.Named("Dog")
static class JakartaDog implements Animal {
@@ -725,16 +681,6 @@ class InjectAnnotationAutowireContextTests {
}
@javax.inject.Named("Dog")
static class JavaxDog implements Animal {
@Override
public String getName() {
return "Javax Fido";
}
}
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier

View File

@@ -23,10 +23,7 @@ import java.lang.annotation.Target;
import java.util.List;
import example.scannable.DefaultNamedComponent;
import example.scannable.JakartaManagedBeanComponent;
import example.scannable.JakartaNamedComponent;
import example.scannable.JavaxManagedBeanComponent;
import example.scannable.JavaxNamedComponent;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
@@ -108,21 +105,6 @@ class AnnotationBeanNameGeneratorTests {
assertGeneratedName(JakartaNamedComponent.class, "myJakartaNamedComponent");
}
@Test
void generateBeanNameWithJavaxNamedComponent() {
assertGeneratedName(JavaxNamedComponent.class, "myJavaxNamedComponent");
}
@Test
void generateBeanNameWithJakartaManagedBeanComponent() {
assertGeneratedName(JakartaManagedBeanComponent.class, "myJakartaManagedBeanComponent");
}
@Test
void generateBeanNameWithJavaxManagedBeanComponent() {
assertGeneratedName(JavaxManagedBeanComponent.class, "myJavaxManagedBeanComponent");
}
@Test
void generateBeanNameWithCustomStereotypeComponent() {
assertGeneratedName(DefaultNamedComponent.class, "thoreau");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -27,10 +27,7 @@ import java.util.regex.Pattern;
import java.util.stream.Stream;
import example.gh24375.AnnotatedComponent;
import example.indexed.IndexedJakartaManagedBeanComponent;
import example.indexed.IndexedJakartaNamedComponent;
import example.indexed.IndexedJavaxManagedBeanComponent;
import example.indexed.IndexedJavaxNamedComponent;
import example.profilescan.DevComponent;
import example.profilescan.ProfileAnnotatedComponent;
import example.profilescan.ProfileMetaAnnotatedComponent;
@@ -40,10 +37,7 @@ import example.scannable.DefaultNamedComponent;
import example.scannable.FooDao;
import example.scannable.FooService;
import example.scannable.FooServiceImpl;
import example.scannable.JakartaManagedBeanComponent;
import example.scannable.JakartaNamedComponent;
import example.scannable.JavaxManagedBeanComponent;
import example.scannable.JavaxNamedComponent;
import example.scannable.MessageBean;
import example.scannable.NamedComponent;
import example.scannable.NamedStubDao;
@@ -99,51 +93,31 @@ class ClassPathScanningCandidateComponentProviderTests {
BarComponent.class
);
private static final Set<Class<?>> scannedJakartaComponents = Set.of(
JakartaNamedComponent.class,
JakartaManagedBeanComponent.class
);
private static final Set<Class<?>> scannedJavaxComponents = Set.of(
JavaxNamedComponent.class,
JavaxManagedBeanComponent.class
);
private static final Set<Class<?>> indexedComponents = Set.of(
IndexedJakartaNamedComponent.class,
IndexedJakartaManagedBeanComponent.class,
IndexedJavaxNamedComponent.class,
IndexedJavaxManagedBeanComponent.class
);
@Test
void defaultsWithScan() {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
provider.setResourceLoader(new DefaultResourceLoader(
CandidateComponentsTestClassLoader.disableIndex(getClass().getClassLoader())));
testDefault(provider, TEST_BASE_PACKAGE, true, true, false);
testDefault(provider, TEST_BASE_PACKAGE, true, false);
}
@Test
void defaultsWithIndex() {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
provider.setResourceLoader(new DefaultResourceLoader(TEST_BASE_CLASSLOADER));
testDefault(provider, "example", true, true, true);
testDefault(provider, "example", true, true);
}
private void testDefault(ClassPathScanningCandidateComponentProvider provider, String basePackage,
boolean includeScannedJakartaComponents, boolean includeScannedJavaxComponents, boolean includeIndexedComponents) {
boolean includeScannedJakartaComponents, boolean includeIndexedComponents) {
Set<Class<?>> expectedTypes = new HashSet<>(springComponents);
if (includeScannedJakartaComponents) {
expectedTypes.addAll(scannedJakartaComponents);
}
if (includeScannedJavaxComponents) {
expectedTypes.addAll(scannedJavaxComponents);
expectedTypes.add(JakartaNamedComponent.class);
}
if (includeIndexedComponents) {
expectedTypes.addAll(indexedComponents);
expectedTypes.add(IndexedJakartaNamedComponent.class);
}
Set<BeanDefinition> candidates = provider.findCandidateComponents(basePackage);
@@ -216,7 +190,7 @@ class ClassPathScanningCandidateComponentProviderTests {
private void testCustomAnnotationTypeIncludeFilter(ClassPathScanningCandidateComponentProvider provider) {
provider.addIncludeFilter(new AnnotationTypeFilter(Component.class));
testDefault(provider, TEST_BASE_PACKAGE, false, false, false);
testDefault(provider, TEST_BASE_PACKAGE, false, false);
}
@Test
@@ -309,7 +283,7 @@ class ClassPathScanningCandidateComponentProviderTests {
Set<BeanDefinition> candidates = provider.findCandidateComponents(TEST_BASE_PACKAGE);
assertScannedBeanDefinitions(candidates);
assertBeanTypes(candidates, FooServiceImpl.class, StubFooDao.class, ServiceInvocationCounter.class,
BarComponent.class, JakartaManagedBeanComponent.class, JavaxManagedBeanComponent.class);
BarComponent.class);
}
@Test

View File

@@ -116,16 +116,6 @@ class CommonAnnotationBeanPostProcessorTests {
assertThat(bean.destroyCalled).isTrue();
}
@Test
void postConstructAndPreDestroyWithLegacyAnnotations() {
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(LegacyAnnotatedInitDestroyBean.class));
LegacyAnnotatedInitDestroyBean bean = (LegacyAnnotatedInitDestroyBean) bf.getBean("annotatedBean");
assertThat(bean.initCalled).isTrue();
bf.destroySingletons();
assertThat(bean.destroyCalled).isTrue();
}
@Test
void postConstructAndPreDestroyWithManualConfiguration() {
InitDestroyAnnotationBeanPostProcessor bpp = new InitDestroyAnnotationBeanPostProcessor();
@@ -223,26 +213,6 @@ class CommonAnnotationBeanPostProcessorTests {
assertThat(bean.destroy3Called).isTrue();
}
@Test
void resourceInjectionWithLegacyAnnotations() {
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
void resourceInjectionWithResolvableDependencyType() {
bpp.setBeanFactory(bf);
@@ -558,30 +528,6 @@ 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
@@ -691,83 +637,6 @@ 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

@@ -10,9 +10,4 @@ example.scannable.ServiceInvocationCounter=org.springframework.stereotype.Compon
example.scannable.sub.BarComponent=org.springframework.stereotype.Component
example.scannable.JakartaManagedBeanComponent=jakarta.annotation.ManagedBean
example.scannable.JakartaNamedComponent=jakarta.inject.Named
example.scannable.JavaxManagedBeanComponent=javax.annotation.ManagedBean
example.scannable.JavaxNamedComponent=javax.inject.Named
example.indexed.IndexedJakartaManagedBeanComponent=jakarta.annotation.ManagedBean
example.indexed.IndexedJakartaNamedComponent=jakarta.inject.Named
example.indexed.IndexedJavaxManagedBeanComponent=javax.annotation.ManagedBean
example.indexed.IndexedJavaxNamedComponent=javax.inject.Named