Allow meta-annotations to override attributes from their parent
Issue: SPR-10181
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -55,7 +55,8 @@ import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.PriorityOrdered;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -235,7 +236,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
Constructor<?> requiredConstructor = null;
|
||||
Constructor<?> defaultConstructor = null;
|
||||
for (Constructor<?> candidate : rawCandidates) {
|
||||
Annotation annotation = findAutowiredAnnotation(candidate);
|
||||
AnnotationAttributes annotation = findAutowiredAnnotation(candidate);
|
||||
if (annotation != null) {
|
||||
if (requiredConstructor != null) {
|
||||
throw new BeanCreationException("Invalid autowire-marked constructor: " + candidate +
|
||||
@@ -333,7 +334,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
do {
|
||||
LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
for (Field field : targetClass.getDeclaredFields()) {
|
||||
Annotation annotation = findAutowiredAnnotation(field);
|
||||
AnnotationAttributes annotation = findAutowiredAnnotation(field);
|
||||
if (annotation != null) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
@@ -347,7 +348,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
}
|
||||
for (Method method : targetClass.getDeclaredMethods()) {
|
||||
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
|
||||
Annotation annotation = BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod) ?
|
||||
AnnotationAttributes annotation = BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod) ?
|
||||
findAutowiredAnnotation(bridgedMethod) : findAutowiredAnnotation(method);
|
||||
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
@@ -374,9 +375,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
return new InjectionMetadata(clazz, elements);
|
||||
}
|
||||
|
||||
private Annotation findAutowiredAnnotation(AccessibleObject ao) {
|
||||
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
|
||||
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
|
||||
Annotation annotation = AnnotationUtils.getAnnotation(ao, type);
|
||||
AnnotationAttributes annotation = AnnotatedElementUtils.getAnnotationAttributes(ao, type.getName());
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
}
|
||||
@@ -384,6 +385,19 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the annotated field or method requires its dependency.
|
||||
* <p>A 'required' dependency means that autowiring should fail when no beans
|
||||
* are found. Otherwise, the autowiring process will simply bypass the field
|
||||
* or method when no beans are found.
|
||||
* @param annotation the Autowired annotation
|
||||
* @return whether the annotation indicates that a dependency is required
|
||||
*/
|
||||
protected boolean determineRequiredStatus(AnnotationAttributes annotation) {
|
||||
return (!annotation.containsKey(this.requiredParameterName) ||
|
||||
this.requiredParameterValue == annotation.getBoolean(this.requiredParameterName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain all beans of the given type as autowire candidates.
|
||||
* @param type the type of the bean
|
||||
@@ -398,31 +412,6 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
return BeanFactoryUtils.beansOfTypeIncludingAncestors(this.beanFactory, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the annotated field or method requires its dependency.
|
||||
* <p>A 'required' dependency means that autowiring should fail when no beans
|
||||
* are found. Otherwise, the autowiring process will simply bypass the field
|
||||
* or method when no beans are found.
|
||||
* @param annotation the Autowired annotation
|
||||
* @return whether the annotation indicates that a dependency is required
|
||||
*/
|
||||
protected boolean determineRequiredStatus(Annotation annotation) {
|
||||
try {
|
||||
Method method = ReflectionUtils.findMethod(annotation.annotationType(), this.requiredParameterName);
|
||||
if (method == null) {
|
||||
// annotations like @Inject and @Value don't have a method (attribute) named "required"
|
||||
// -> default to required status
|
||||
return true;
|
||||
}
|
||||
return (this.requiredParameterValue == (Boolean) ReflectionUtils.invokeMethod(method, annotation));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// an exception was thrown during reflective invocation of the required attribute
|
||||
// -> default to required status
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the specified bean as dependent on the autowired beans.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user