full compliance with the JSR-330 TCK
This commit is contained in:
@@ -27,6 +27,7 @@ import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -270,28 +271,16 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
return (candidateConstructors.length > 0 ? candidateConstructors : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
|
||||
InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());
|
||||
try {
|
||||
metadata.injectFields(bean, beanName);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Autowiring of fields failed", ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
|
||||
|
||||
InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());
|
||||
try {
|
||||
metadata.injectMethods(bean, beanName, pvs);
|
||||
metadata.inject(bean, beanName, pvs);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Autowiring of methods failed", ex);
|
||||
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
|
||||
}
|
||||
return pvs;
|
||||
}
|
||||
@@ -300,15 +289,16 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
* 'Native' processing method for direct calls with an arbitrary target instance,
|
||||
* resolving all of its fields and methods which are annotated with <code>@Autowired</code>.
|
||||
* @param bean the target instance to process
|
||||
* @throws BeansException if autowiring failed
|
||||
*/
|
||||
public void processInjection(Object bean) throws BeansException {
|
||||
InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());
|
||||
Class<?> clazz = bean.getClass();
|
||||
InjectionMetadata metadata = findAutowiringMetadata(clazz);
|
||||
try {
|
||||
metadata.injectFields(bean, null);
|
||||
metadata.injectMethods(bean, null, null);
|
||||
metadata.inject(bean, null, null);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException("Autowiring of fields/methods failed", ex);
|
||||
throw new BeanCreationException("Injection of autowired dependencies failed for class [" + clazz + "]", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,36 +310,49 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
synchronized (this.injectionMetadataCache) {
|
||||
metadata = this.injectionMetadataCache.get(clazz);
|
||||
if (metadata == null) {
|
||||
final InjectionMetadata newMetadata = new InjectionMetadata(clazz);
|
||||
ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
|
||||
public void doWith(Field field) {
|
||||
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
Class<?> targetClass = clazz;
|
||||
|
||||
do {
|
||||
LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
for (Field field : targetClass.getDeclaredFields()) {
|
||||
Annotation annotation = findAutowiredAnnotation(field);
|
||||
if (annotation != null) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
throw new IllegalStateException("Autowired annotation is not supported on static fields");
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Autowired annotation is not supported on static fields: " + field);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
boolean required = determineRequiredStatus(annotation);
|
||||
newMetadata.addInjectedField(new AutowiredFieldElement(field, required));
|
||||
currElements.add(new AutowiredFieldElement(field, required));
|
||||
}
|
||||
}
|
||||
});
|
||||
ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
|
||||
public void doWith(Method method) {
|
||||
for (Method method : targetClass.getDeclaredMethods()) {
|
||||
Annotation annotation = findAutowiredAnnotation(method);
|
||||
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
throw new IllegalStateException("Autowired annotation is not supported on static methods");
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Autowired annotation is not supported on static methods: " + method);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (method.getParameterTypes().length == 0) {
|
||||
throw new IllegalStateException("Autowired annotation requires at least one argument: " + method);
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Autowired annotation should be used on methods with actual parameters: " + method);
|
||||
}
|
||||
}
|
||||
boolean required = determineRequiredStatus(annotation);
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
|
||||
newMetadata.addInjectedMethod(new AutowiredMethodElement(method, required, pd));
|
||||
currElements.add(new AutowiredMethodElement(method, required, pd));
|
||||
}
|
||||
}
|
||||
});
|
||||
metadata = newMetadata;
|
||||
elements.addAll(0, currElements);
|
||||
targetClass = targetClass.getSuperclass();
|
||||
}
|
||||
while (targetClass != null && targetClass != Object.class);
|
||||
|
||||
metadata = new InjectionMetadata(clazz, elements);
|
||||
this.injectionMetadataCache.put(clazz, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,42 +49,21 @@ public class InjectionMetadata {
|
||||
|
||||
private final Log logger = LogFactory.getLog(InjectionMetadata.class);
|
||||
|
||||
private String targetClassName;
|
||||
|
||||
private final Set<InjectedElement> injectedFields = new LinkedHashSet<InjectedElement>();
|
||||
|
||||
private final Set<InjectedElement> injectedMethods = new LinkedHashSet<InjectedElement>();
|
||||
private final Set<InjectedElement> injectedElements;
|
||||
|
||||
|
||||
public InjectionMetadata() {
|
||||
}
|
||||
|
||||
public InjectionMetadata(Class targetClass) {
|
||||
this.targetClassName = targetClass.getName();
|
||||
}
|
||||
|
||||
|
||||
public void addInjectedField(InjectedElement element) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found injected field on class [" + this.targetClassName + "]: " + element);
|
||||
public InjectionMetadata(Class targetClass, Collection<InjectedElement> elements) {
|
||||
this.injectedElements = new LinkedHashSet<InjectedElement>();
|
||||
for (InjectedElement element : elements) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found injected element on class [" + targetClass.getName() + "]: " + element);
|
||||
}
|
||||
this.injectedElements.add(element);
|
||||
}
|
||||
this.injectedFields.add(element);
|
||||
}
|
||||
|
||||
public void addInjectedMethod(InjectedElement element) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found injected method on class [" + this.targetClassName + "]: " + element);
|
||||
}
|
||||
this.injectedMethods.add(element);
|
||||
}
|
||||
|
||||
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
|
||||
doRegisterConfigMembers(beanDefinition, this.injectedFields);
|
||||
doRegisterConfigMembers(beanDefinition, this.injectedMethods);
|
||||
}
|
||||
|
||||
private void doRegisterConfigMembers(RootBeanDefinition beanDefinition, Collection<InjectedElement> members) {
|
||||
for (Iterator<InjectedElement> it = members.iterator(); it.hasNext();) {
|
||||
for (Iterator<InjectedElement> it = this.injectedElements.iterator(); it.hasNext();) {
|
||||
Member member = it.next().getMember();
|
||||
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
|
||||
beanDefinition.registerExternallyManagedConfigMember(member);
|
||||
@@ -95,22 +74,10 @@ public class InjectionMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
public void injectFields(Object target, String beanName) throws Throwable {
|
||||
if (!this.injectedFields.isEmpty()) {
|
||||
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
|
||||
if (!this.injectedElements.isEmpty()) {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (InjectedElement element : this.injectedFields) {
|
||||
if (debug) {
|
||||
logger.debug("Processing injected field of bean '" + beanName + "': " + element);
|
||||
}
|
||||
element.inject(target, beanName, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void injectMethods(Object target, String beanName, PropertyValues pvs) throws Throwable {
|
||||
if (!this.injectedMethods.isEmpty()) {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (InjectedElement element : this.injectedMethods) {
|
||||
for (InjectedElement element : this.injectedElements) {
|
||||
if (debug) {
|
||||
logger.debug("Processing injected method of bean '" + beanName + "': " + element);
|
||||
}
|
||||
|
||||
@@ -780,12 +780,18 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class beanType, String beanName)
|
||||
throws BeansException {
|
||||
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof MergedBeanDefinitionPostProcessor) {
|
||||
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
|
||||
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
|
||||
try {
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof MergedBeanDefinitionPostProcessor) {
|
||||
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
|
||||
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
"Post-processing failed of bean type [" + beanType + "] failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -16,12 +16,10 @@
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -152,8 +150,8 @@ public class BeanDefinitionReaderUtils {
|
||||
// Register aliases for bean name, if any.
|
||||
String[] aliases = definitionHolder.getAliases();
|
||||
if (aliases != null) {
|
||||
for (int i = 0; i < aliases.length; i++) {
|
||||
registry.registerAlias(beanName, aliases[i]);
|
||||
for (String aliase : aliases) {
|
||||
registry.registerAlias(beanName, aliase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user