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:
@@ -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"));
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user