Retain support for legacy PostConstruct/PreDestroy/Inject variants
Also removes JAX-WS support from CommonAnnotationBeanPostProcessor. Closes gh-27444 See gh-27422
This commit is contained in:
parent
6976bf774b
commit
774583dfa7
|
|
@ -230,7 +230,6 @@ configure(allprojects) { project ->
|
|||
dependency "jakarta.validation:jakarta.validation-api:3.0.0"
|
||||
dependency "jakarta.websocket:jakarta.websocket-api:2.0.0"
|
||||
dependency "jakarta.xml.bind:jakarta.xml.bind-api:3.0.1"
|
||||
dependency "jakarta.xml.ws:jakarta.xml.ws-api:3.0.1"
|
||||
|
||||
dependency "com.sun.activation:jakarta.activation:2.0.1"
|
||||
dependency "com.sun.mail:jakarta.mail:2.0.1"
|
||||
|
|
|
|||
|
|
@ -75,8 +75,10 @@ import org.springframework.util.StringUtils;
|
|||
* by default, Spring's {@link Autowired @Autowired} and {@link Value @Value}
|
||||
* annotations.
|
||||
*
|
||||
* <p>Also supports JSR-330's {@link jakarta.inject.Inject @Inject} annotation,
|
||||
* <p>Also supports the common {@link jakarta.inject.Inject @Inject} annotation,
|
||||
* if available, as a direct alternative to Spring's own {@code @Autowired}.
|
||||
* Additionally, it retains support for the {@code javax.inject.Inject} variant
|
||||
* dating back to the original JSR-330 specification (as known from Java EE 6-8).
|
||||
*
|
||||
* <h3>Autowired Constructors</h3>
|
||||
* <p>Only one constructor of any given bean class may declare this annotation with
|
||||
|
|
@ -154,20 +156,30 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
|||
/**
|
||||
* Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
|
||||
* standard {@link Autowired @Autowired} and {@link Value @Value} annotations.
|
||||
* <p>Also supports JSR-330's {@link jakarta.inject.Inject @Inject} annotation,
|
||||
* if available.
|
||||
* <p>Also supports the common {@link jakarta.inject.Inject @Inject} annotation,
|
||||
* if available, as well as the original {@code javax.inject.Inject} variant.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public AutowiredAnnotationBeanPostProcessor() {
|
||||
this.autowiredAnnotationTypes.add(Autowired.class);
|
||||
this.autowiredAnnotationTypes.add(Value.class);
|
||||
|
||||
try {
|
||||
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
|
||||
ClassUtils.forName("jakarta.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
|
||||
logger.trace("JSR-330 'jakarta.inject.Inject' annotation found and supported for autowiring");
|
||||
logger.trace("'jakarta.inject.Inject' annotation found and supported for autowiring");
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// JSR-330 API not available - simply skip.
|
||||
// jakarta.inject API not available - simply skip.
|
||||
}
|
||||
|
||||
try {
|
||||
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
|
||||
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
|
||||
logger.trace("'javax.inject.Inject' annotation found and supported for autowiring");
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// javax.inject API not available - simply skip.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -177,7 +189,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
|||
* setter methods, and arbitrary config methods.
|
||||
* <p>The default autowired annotation types are the Spring-provided
|
||||
* {@link Autowired @Autowired} and {@link Value @Value} annotations as well
|
||||
* as JSR-330's {@link jakarta.inject.Inject @Inject} annotation, if available.
|
||||
* as the common {@code @Inject} annotation, if available.
|
||||
* <p>This setter property exists so that developers can provide their own
|
||||
* (non-Spring-specific) annotation type to indicate that a member is supposed
|
||||
* to be autowired.
|
||||
|
|
@ -193,7 +205,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
|||
* setter methods, and arbitrary config methods.
|
||||
* <p>The default autowired annotation types are the Spring-provided
|
||||
* {@link Autowired @Autowired} and {@link Value @Value} annotations as well
|
||||
* as JSR-330's {@link jakarta.inject.Inject @Inject} annotation, if available.
|
||||
* as the common {@code @Inject} annotation, if available.
|
||||
* <p>This setter property exists so that developers can provide their own
|
||||
* (non-Spring-specific) annotation types to indicate that a member is supposed
|
||||
* to be autowired.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
|
@ -66,7 +66,7 @@ import org.springframework.util.ReflectionUtils;
|
|||
* init method and destroy method, respectively.
|
||||
*
|
||||
* <p>Spring's {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor}
|
||||
* supports the JSR-250 {@link jakarta.annotation.PostConstruct} and {@link jakarta.annotation.PreDestroy}
|
||||
* supports the {@link jakarta.annotation.PostConstruct} and {@link jakarta.annotation.PreDestroy}
|
||||
* annotations out of the box, as init annotation and destroy annotation, respectively.
|
||||
* Furthermore, it also supports the {@link jakarta.annotation.Resource} annotation
|
||||
* for annotation-driven injection of named beans.
|
||||
|
|
@ -117,7 +117,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
|||
* methods to call after configuration of a bean.
|
||||
* <p>Any custom annotation can be used, since there are no required
|
||||
* annotation attributes. There is no default, although a typical choice
|
||||
* is the JSR-250 {@link jakarta.annotation.PostConstruct} annotation.
|
||||
* is the {@link jakarta.annotation.PostConstruct} annotation.
|
||||
*/
|
||||
public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
|
||||
this.initAnnotationType = initAnnotationType;
|
||||
|
|
@ -128,7 +128,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
|||
* methods to call when the context is shutting down.
|
||||
* <p>Any custom annotation can be used, since there are no required
|
||||
* annotation attributes. There is no default, although a typical choice
|
||||
* is the JSR-250 {@link jakarta.annotation.PreDestroy} annotation.
|
||||
* is the {@link jakarta.annotation.PreDestroy} annotation.
|
||||
*/
|
||||
public void setDestroyAnnotationType(Class<? extends Annotation> destroyAnnotationType) {
|
||||
this.destroyAnnotationType = destroyAnnotationType;
|
||||
|
|
|
|||
|
|
@ -14,9 +14,8 @@ dependencies {
|
|||
optional("jakarta.enterprise.concurrent:jakarta.enterprise.concurrent-api")
|
||||
optional("jakarta.inject:jakarta.inject-api")
|
||||
optional("jakarta.interceptor:jakarta.interceptor-api")
|
||||
optional("javax.money:money-api")
|
||||
optional("jakarta.validation:jakarta.validation-api")
|
||||
optional("jakarta.xml.ws:jakarta.xml.ws-api")
|
||||
optional("javax.money:money-api")
|
||||
optional("org.aspectj:aspectjweaver")
|
||||
optional("org.codehaus.groovy:groovy")
|
||||
optional("org.apache-extras.beanshell:bsh")
|
||||
|
|
@ -32,8 +31,8 @@ dependencies {
|
|||
testImplementation("org.codehaus.groovy:groovy-test")
|
||||
testImplementation("org.codehaus.groovy:groovy-xml")
|
||||
testImplementation("org.apache.commons:commons-pool2")
|
||||
testImplementation("jakarta.inject:jakarta.inject-tck")
|
||||
testImplementation("org.awaitility:awaitility")
|
||||
testImplementation("jakarta.inject:jakarta.inject-tck")
|
||||
testRuntimeOnly("jakarta.xml.bind:jakarta.xml.bind-api")
|
||||
testRuntimeOnly("org.glassfish:jakarta.el")
|
||||
// Substitute for javax.management:jmxremote_optional:1.0.1_04 (not available on Maven Central)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
|
@ -23,6 +23,7 @@ import java.util.Set;
|
|||
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
|
||||
import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
|
|
@ -91,11 +92,17 @@ public abstract class AnnotationConfigUtils {
|
|||
"org.springframework.context.annotation.internalRequiredAnnotationProcessor";
|
||||
|
||||
/**
|
||||
* The bean name of the internally managed JSR-250 annotation processor.
|
||||
* The bean name of the internally managed common annotation processor.
|
||||
*/
|
||||
public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME =
|
||||
"org.springframework.context.annotation.internalCommonAnnotationProcessor";
|
||||
|
||||
/**
|
||||
* The bean name of the internally managed JSR-250 annotation processor.
|
||||
*/
|
||||
private static final String JSR250_ANNOTATION_PROCESSOR_BEAN_NAME =
|
||||
"org.springframework.context.annotation.internalJsr250AnnotationProcessor";
|
||||
|
||||
/**
|
||||
* The bean name of the internally managed JPA annotation processor.
|
||||
*/
|
||||
|
|
@ -117,16 +124,18 @@ public abstract class AnnotationConfigUtils {
|
|||
public static final String EVENT_LISTENER_FACTORY_BEAN_NAME =
|
||||
"org.springframework.context.event.internalEventListenerFactory";
|
||||
|
||||
private static final boolean jsr250Present;
|
||||
|
||||
private static final boolean jpaPresent;
|
||||
private static final ClassLoader classLoader = AnnotationConfigUtils.class.getClassLoader();
|
||||
|
||||
static {
|
||||
ClassLoader classLoader = AnnotationConfigUtils.class.getClassLoader();
|
||||
jsr250Present = ClassUtils.isPresent("jakarta.annotation.Resource", classLoader);
|
||||
jpaPresent = ClassUtils.isPresent("jakarta.persistence.EntityManagerFactory", classLoader) &&
|
||||
ClassUtils.isPresent(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, classLoader);
|
||||
}
|
||||
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);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -172,13 +181,28 @@ public abstract class AnnotationConfigUtils {
|
|||
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
|
||||
}
|
||||
|
||||
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
|
||||
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||||
// Check for Jakarta Annotations support, and if present add the CommonAnnotationBeanPostProcessor.
|
||||
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));
|
||||
}
|
||||
|
||||
// Check for JSR-250 support, and if present add an InitDestroyAnnotationBeanPostProcessor
|
||||
// for the javax variant of PostConstruct/PreDestroy.
|
||||
if (jsr250Present && !registry.containsBeanDefinition(JSR250_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||||
try {
|
||||
RootBeanDefinition def = new RootBeanDefinition(InitDestroyAnnotationBeanPostProcessor.class);
|
||||
def.getPropertyValues().add("initAnnotationType", classLoader.loadClass("javax.annotation.PostConstruct"));
|
||||
def.getPropertyValues().add("destroyAnnotationType", classLoader.loadClass("javax.annotation.PreDestroy"));
|
||||
def.setSource(source);
|
||||
beanDefs.add(registerPostProcessor(registry, def, JSR250_ANNOTATION_PROCESSOR_BEAN_NAME));
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Failed to load javax variants of the annotation types -> ignore.
|
||||
}
|
||||
}
|
||||
|
||||
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
|
||||
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||||
RootBeanDefinition def = new RootBeanDefinition();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
|
@ -21,13 +21,10 @@ import java.beans.PropertyDescriptor;
|
|||
import java.io.Serializable;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
|
@ -37,15 +34,10 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.ejb.EJB;
|
||||
import jakarta.xml.ws.Service;
|
||||
import jakarta.xml.ws.WebServiceClient;
|
||||
import jakarta.xml.ws.WebServiceRef;
|
||||
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
|
|
@ -77,10 +69,9 @@ import org.springframework.util.StringValueResolver;
|
|||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
|
||||
* that supports common Java annotations out of the box, in particular the JSR-250
|
||||
* that supports common Java annotations out of the box, in particular the common
|
||||
* annotations in the {@code jakarta.annotation} package. These common Java
|
||||
* annotations are supported in many Jakarta EE technologies (e.g. JSF 1.2),
|
||||
* as well as in Java 6's JAX-WS.
|
||||
* annotations are supported in many Jakarta EE technologies (e.g. JSF and JAX-RS).
|
||||
*
|
||||
* <p>This post-processor includes support for the {@link jakarta.annotation.PostConstruct}
|
||||
* and {@link jakarta.annotation.PreDestroy} annotations - as init annotation
|
||||
|
|
@ -95,12 +86,8 @@ 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>The JAX-WS {@link javax.xml.ws.WebServiceRef} annotation is supported too,
|
||||
* analogous to {@link jakarta.annotation.Resource} but with the capability of creating
|
||||
* specific JAX-WS service endpoints. This may either point to an explicitly defined
|
||||
* resource by name or operate on a locally specified JAX-WS service class. Finally,
|
||||
* this post-processor also supports the EJB 3 {@link jakarta.ejb.EJB} annotation,
|
||||
* analogous to {@link jakarta.annotation.Resource} as well, with the capability to
|
||||
* <p>This post-processor also supports the EJB 3 {@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.
|
||||
* The target beans can be plain POJOs as well as EJB 3 Session Beans in this case.
|
||||
*
|
||||
|
|
@ -143,22 +130,15 @@ import org.springframework.util.StringValueResolver;
|
|||
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
|
||||
implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
|
||||
|
||||
@Nullable
|
||||
private static final Class<? extends Annotation> webServiceRefClass;
|
||||
private static final Set<Class<? extends Annotation>> resourceAnnotationTypes = new LinkedHashSet<>(4);
|
||||
|
||||
@Nullable
|
||||
private static final Class<? extends Annotation> ejbClass;
|
||||
|
||||
private static final Set<Class<? extends Annotation>> resourceAnnotationTypes = new LinkedHashSet<>(4);
|
||||
|
||||
static {
|
||||
webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef");
|
||||
ejbClass = loadAnnotationType("jakarta.ejb.EJB");
|
||||
|
||||
resourceAnnotationTypes.add(Resource.class);
|
||||
if (webServiceRefClass != null) {
|
||||
resourceAnnotationTypes.add(webServiceRefClass);
|
||||
}
|
||||
|
||||
ejbClass = loadAnnotationType("jakarta.ejb.EJB");
|
||||
if (ejbClass != null) {
|
||||
resourceAnnotationTypes.add(ejbClass);
|
||||
}
|
||||
|
|
@ -195,15 +175,11 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
setOrder(Ordered.LOWEST_PRECEDENCE - 3);
|
||||
setInitAnnotationType(PostConstruct.class);
|
||||
setDestroyAnnotationType(PreDestroy.class);
|
||||
ignoreResourceType("javax.xml.ws.WebServiceContext");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ignore the given resource type when resolving {@code @Resource}
|
||||
* annotations.
|
||||
* <p>By default, the {@code javax.xml.ws.WebServiceContext} interface
|
||||
* will be ignored, since it will be resolved by the JAX-WS runtime.
|
||||
* Ignore the given resource type when resolving {@code @Resource} annotations.
|
||||
* @param resourceType the resource type to ignore
|
||||
*/
|
||||
public void ignoreResourceType(String resourceType) {
|
||||
|
|
@ -361,13 +337,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
|
||||
|
||||
ReflectionUtils.doWithLocalFields(targetClass, field -> {
|
||||
if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
|
||||
}
|
||||
currElements.add(new WebServiceRefElement(field, field, null));
|
||||
}
|
||||
else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {
|
||||
if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
throw new IllegalStateException("@EJB annotation is not supported on static fields");
|
||||
}
|
||||
|
|
@ -389,17 +359,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
return;
|
||||
}
|
||||
if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
|
||||
if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
|
||||
}
|
||||
if (method.getParameterCount() != 1) {
|
||||
throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
|
||||
}
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
|
||||
currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
|
||||
}
|
||||
else if (ejbClass != null && bridgedMethod.isAnnotationPresent(ejbClass)) {
|
||||
if (ejbClass != null && bridgedMethod.isAnnotationPresent(ejbClass)) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
throw new IllegalStateException("@EJB annotation is not supported on static methods");
|
||||
}
|
||||
|
|
@ -649,91 +609,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class representing injection information about an annotated field
|
||||
* or setter method, supporting the @WebServiceRef annotation.
|
||||
*/
|
||||
private class WebServiceRefElement extends LookupElement {
|
||||
|
||||
private final Class<?> elementType;
|
||||
|
||||
private final String wsdlLocation;
|
||||
|
||||
public WebServiceRefElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
|
||||
super(member, pd);
|
||||
WebServiceRef resource = ae.getAnnotation(WebServiceRef.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 = Introspector.decapitalize(resourceName.substring(3));
|
||||
}
|
||||
}
|
||||
if (Object.class != resourceType) {
|
||||
checkResourceType(resourceType);
|
||||
}
|
||||
else {
|
||||
// No resource type specified... check field/method.
|
||||
resourceType = getResourceType();
|
||||
}
|
||||
this.name = resourceName;
|
||||
this.elementType = resourceType;
|
||||
if (Service.class.isAssignableFrom(resourceType)) {
|
||||
this.lookupType = resourceType;
|
||||
}
|
||||
else {
|
||||
this.lookupType = resource.value();
|
||||
}
|
||||
this.mappedName = resource.mappedName();
|
||||
this.wsdlLocation = resource.wsdlLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
|
||||
Service service;
|
||||
try {
|
||||
service = (Service) getResource(this, requestingBeanName);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException notFound) {
|
||||
// Service to be created through generated class.
|
||||
if (Service.class == this.lookupType) {
|
||||
throw new IllegalStateException("No resource with name '" + this.name + "' found in context, " +
|
||||
"and no specific JAX-WS Service subclass specified. The typical solution is to either specify " +
|
||||
"a LocalJaxWsServiceFactoryBean with the given name or to specify the (generated) Service " +
|
||||
"subclass as @WebServiceRef(...) value.");
|
||||
}
|
||||
if (StringUtils.hasLength(this.wsdlLocation)) {
|
||||
try {
|
||||
Constructor<?> ctor = this.lookupType.getConstructor(URL.class, QName.class);
|
||||
WebServiceClient clientAnn = this.lookupType.getAnnotation(WebServiceClient.class);
|
||||
if (clientAnn == null) {
|
||||
throw new IllegalStateException("JAX-WS Service class [" + this.lookupType.getName() +
|
||||
"] does not carry a WebServiceClient annotation");
|
||||
}
|
||||
service = (Service) BeanUtils.instantiateClass(ctor,
|
||||
new URL(this.wsdlLocation), new QName(clientAnn.targetNamespace(), clientAnn.name()));
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
throw new IllegalStateException("JAX-WS Service class [" + this.lookupType.getName() +
|
||||
"] does not have a (URL, QName) constructor. Cannot apply specified WSDL location [" +
|
||||
this.wsdlLocation + "].");
|
||||
}
|
||||
catch (MalformedURLException ex) {
|
||||
throw new IllegalArgumentException(
|
||||
"Specified WSDL location [" + this.wsdlLocation + "] isn't a valid URL");
|
||||
}
|
||||
}
|
||||
else {
|
||||
service = (Service) BeanUtils.instantiateClass(this.lookupType);
|
||||
}
|
||||
}
|
||||
return service.getPort(this.elementType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class representing injection information about an annotated field
|
||||
* or setter method, supporting the @EJB annotation.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
|
@ -61,7 +61,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
assertThat(beanCount).isEqualTo(12);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(12);
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isTrue();
|
||||
assertThat(context.containsBean("fooServiceImpl")).isTrue();
|
||||
assertThat(context.containsBean("stubFooDao")).isTrue();
|
||||
|
|
@ -110,7 +110,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
assertThat(beanCount).isEqualTo(12);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(12);
|
||||
|
||||
ClassPathBeanDefinitionScanner scanner2 = new ClassPathBeanDefinitionScanner(context) {
|
||||
@Override
|
||||
|
|
@ -138,7 +138,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
assertThat(beanCount).isEqualTo(12);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(12);
|
||||
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isTrue();
|
||||
assertThat(context.containsBean("fooServiceImpl")).isTrue();
|
||||
|
|
@ -157,7 +157,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
assertThat(beanCount).isEqualTo(12);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(12);
|
||||
|
||||
ClassPathBeanDefinitionScanner scanner2 = new ClassPathBeanDefinitionScanner(context) {
|
||||
@Override
|
||||
|
|
@ -182,7 +182,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
scanner.setIncludeAnnotationConfig(false);
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
assertThat(beanCount).isEqualTo(7);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(7);
|
||||
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isTrue();
|
||||
assertThat(context.containsBean("fooServiceImpl")).isTrue();
|
||||
|
|
@ -222,7 +222,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
scanner.setIncludeAnnotationConfig(false);
|
||||
int scannedBeanCount = scanner.scan(BASE_PACKAGE);
|
||||
|
||||
assertThat(scannedBeanCount).isEqualTo(6);
|
||||
assertThat(scannedBeanCount).isGreaterThanOrEqualTo(6);
|
||||
assertThat(context.getBeanDefinitionCount()).isEqualTo((initialBeanCount + scannedBeanCount));
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isTrue();
|
||||
assertThat(context.containsBean("fooServiceImpl")).isTrue();
|
||||
|
|
@ -242,7 +242,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
scanner.setIncludeAnnotationConfig(false);
|
||||
int scannedBeanCount = scanner.scan(BASE_PACKAGE);
|
||||
|
||||
assertThat(scannedBeanCount).isEqualTo(6);
|
||||
assertThat(scannedBeanCount).isGreaterThanOrEqualTo(6);
|
||||
assertThat(context.getBeanDefinitionCount()).isEqualTo((initialBeanCount + scannedBeanCount));
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isTrue();
|
||||
assertThat(context.containsBean("fooServiceImpl")).isTrue();
|
||||
|
|
@ -281,7 +281,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
scanner.addIncludeFilter(new AnnotationTypeFilter(CustomComponent.class));
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
|
||||
assertThat(beanCount).isEqualTo(6);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(6);
|
||||
assertThat(context.containsBean("messageBean")).isTrue();
|
||||
assertThat(context.containsBean(AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)).isTrue();
|
||||
assertThat(context.containsBean(AnnotationConfigUtils.COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)).isTrue();
|
||||
|
|
@ -296,7 +296,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
scanner.addIncludeFilter(new AnnotationTypeFilter(CustomComponent.class));
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
|
||||
assertThat(beanCount).isEqualTo(6);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(6);
|
||||
assertThat(context.containsBean("messageBean")).isTrue();
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isFalse();
|
||||
assertThat(context.containsBean("fooServiceImpl")).isFalse();
|
||||
|
|
@ -316,7 +316,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
scanner.addIncludeFilter(new AnnotationTypeFilter(CustomComponent.class));
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
|
||||
assertThat(beanCount).isEqualTo(13);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(13);
|
||||
assertThat(context.containsBean("messageBean")).isTrue();
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isTrue();
|
||||
assertThat(context.containsBean("fooServiceImpl")).isTrue();
|
||||
|
|
@ -336,7 +336,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
scanner.addExcludeFilter(new AnnotationTypeFilter(Aspect.class));
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
|
||||
assertThat(beanCount).isEqualTo(11);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(11);
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isFalse();
|
||||
assertThat(context.containsBean("fooServiceImpl")).isTrue();
|
||||
assertThat(context.containsBean("stubFooDao")).isTrue();
|
||||
|
|
@ -354,7 +354,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
scanner.addExcludeFilter(new AssignableTypeFilter(FooService.class));
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
|
||||
assertThat(beanCount).isEqualTo(11);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(11);
|
||||
assertThat(context.containsBean("fooServiceImpl")).isFalse();
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isTrue();
|
||||
assertThat(context.containsBean("stubFooDao")).isTrue();
|
||||
|
|
@ -374,7 +374,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
scanner.addExcludeFilter(new AssignableTypeFilter(FooService.class));
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
|
||||
assertThat(beanCount).isEqualTo(6);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(6);
|
||||
assertThat(context.containsBean("fooServiceImpl")).isFalse();
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isTrue();
|
||||
assertThat(context.containsBean("stubFooDao")).isTrue();
|
||||
|
|
@ -392,7 +392,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
scanner.addExcludeFilter(new AnnotationTypeFilter(Aspect.class));
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
|
||||
assertThat(beanCount).isEqualTo(10);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(10);
|
||||
assertThat(context.containsBean("fooServiceImpl")).isFalse();
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isFalse();
|
||||
assertThat(context.containsBean("stubFooDao")).isTrue();
|
||||
|
|
@ -411,7 +411,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
scanner.setBeanNameGenerator(new TestBeanNameGenerator());
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
|
||||
assertThat(beanCount).isEqualTo(12);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(12);
|
||||
assertThat(context.containsBean("fooServiceImpl")).isFalse();
|
||||
assertThat(context.containsBean("fooService")).isTrue();
|
||||
assertThat(context.containsBean("serviceInvocationCounter")).isTrue();
|
||||
|
|
@ -431,7 +431,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
GenericApplicationContext multiPackageContext = new GenericApplicationContext();
|
||||
ClassPathBeanDefinitionScanner multiPackageScanner = new ClassPathBeanDefinitionScanner(multiPackageContext);
|
||||
int singlePackageBeanCount = singlePackageScanner.scan(BASE_PACKAGE);
|
||||
assertThat(singlePackageBeanCount).isEqualTo(12);
|
||||
assertThat(singlePackageBeanCount).isGreaterThanOrEqualTo(12);
|
||||
multiPackageScanner.scan(BASE_PACKAGE, "org.springframework.dao.annotation");
|
||||
// assertTrue(multiPackageBeanCount > singlePackageBeanCount);
|
||||
}
|
||||
|
|
@ -442,7 +442,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
int initialBeanCount = context.getBeanDefinitionCount();
|
||||
int scannedBeanCount = scanner.scan(BASE_PACKAGE);
|
||||
assertThat(scannedBeanCount).isEqualTo(12);
|
||||
assertThat(scannedBeanCount).isGreaterThanOrEqualTo(12);
|
||||
assertThat((context.getBeanDefinitionCount() - initialBeanCount)).isEqualTo(scannedBeanCount);
|
||||
int addedBeanCount = scanner.scan("org.springframework.aop.aspectj.annotation");
|
||||
assertThat(context.getBeanDefinitionCount()).isEqualTo((initialBeanCount + scannedBeanCount + addedBeanCount));
|
||||
|
|
@ -455,7 +455,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
scanner.setBeanNameGenerator(new TestBeanNameGenerator());
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
assertThat(beanCount).isEqualTo(12);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(12);
|
||||
context.refresh();
|
||||
|
||||
FooServiceImpl fooService = context.getBean("fooService", FooServiceImpl.class);
|
||||
|
|
@ -485,7 +485,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
scanner.setIncludeAnnotationConfig(false);
|
||||
scanner.setBeanNameGenerator(new TestBeanNameGenerator());
|
||||
int beanCount = scanner.scan(BASE_PACKAGE);
|
||||
assertThat(beanCount).isEqualTo(7);
|
||||
assertThat(beanCount).isGreaterThanOrEqualTo(7);
|
||||
context.refresh();
|
||||
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in New Issue