initial JSR-330 injection support
This commit is contained in:
@@ -83,6 +83,8 @@ import org.springframework.util.ReflectionUtils;
|
||||
* a special case of such a general config method. Such config methods
|
||||
* do not have to be public.
|
||||
*
|
||||
* <p>Also supports JSR-330's {@link javax.inject.Inject} annotation, if available.
|
||||
*
|
||||
* <p>Note: A default AutowiredAnnotationBeanPostProcessor will be registered
|
||||
* by the "context:annotation-config" and "context:component-scan" XML tags.
|
||||
* Remove or turn off the default annotation configuration there if you intend
|
||||
@@ -100,8 +102,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
|
||||
protected final Log logger = LogFactory.getLog(AutowiredAnnotationBeanPostProcessor.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<? extends Annotation>[] autowiredAnnotationTypes = new Class[] {Autowired.class, Value.class};
|
||||
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes =
|
||||
new LinkedHashSet<Class<? extends Annotation>>();
|
||||
|
||||
private String requiredParameterName = "required";
|
||||
|
||||
@@ -119,20 +121,24 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
|
||||
|
||||
/**
|
||||
* Set the 'autowired' annotation types, to be used on constructors, fields,
|
||||
* setter methods and arbitrary config methods.
|
||||
* <p>The default autowired annotation type is the Spring-provided
|
||||
* {@link Autowired} annotation, as well as {@link Value} and raw
|
||||
* use of the {@link Qualifier} annotation.
|
||||
* <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.
|
||||
* Create a new AutowiredAnnotationBeanPostProcessor
|
||||
* for Spring's standard {@link Autowired} annotation.
|
||||
* <p>Also supports JSR-330's {@link javax.inject.Inject} annotation, if available.
|
||||
*/
|
||||
public void setAutowiredAnnotationTypes(Class<? extends Annotation>[] autowiredAnnotationTypes) {
|
||||
Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty");
|
||||
this.autowiredAnnotationTypes = autowiredAnnotationTypes;
|
||||
@SuppressWarnings("unchecked")
|
||||
public AutowiredAnnotationBeanPostProcessor() {
|
||||
this.autowiredAnnotationTypes.add(Autowired.class);
|
||||
this.autowiredAnnotationTypes.add(Value.class);
|
||||
ClassLoader cl = AutowiredAnnotationBeanPostProcessor.class.getClassLoader();
|
||||
try {
|
||||
this.autowiredAnnotationTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Inject"));
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// JSR-330 API not available - simply skip.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the 'autowired' annotation type, to be used on constructors, fields,
|
||||
* setter methods and arbitrary config methods.
|
||||
@@ -142,10 +148,26 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
* (non-Spring-specific) annotation type to indicate that a member is
|
||||
* supposed to be autowired.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) {
|
||||
Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
|
||||
this.autowiredAnnotationTypes = new Class[] {autowiredAnnotationType};
|
||||
this.autowiredAnnotationTypes.clear();
|
||||
this.autowiredAnnotationTypes.add(autowiredAnnotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'autowired' annotation types, to be used on constructors, fields,
|
||||
* setter methods and arbitrary config methods.
|
||||
* <p>The default autowired annotation type is the Spring-provided
|
||||
* {@link Autowired} annotation, as well as {@link Value} and raw
|
||||
* use of the {@link Qualifier} annotation.
|
||||
* <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.
|
||||
*/
|
||||
public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> autowiredAnnotationTypes) {
|
||||
Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty");
|
||||
this.autowiredAnnotationTypes.clear();
|
||||
this.autowiredAnnotationTypes.addAll(autowiredAnnotationTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.beans.factory.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -38,9 +38,11 @@ import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* {@link AutowireCandidateResolver} implementation that matches bean definition
|
||||
* qualifiers against qualifier annotations on the field or parameter to be autowired.
|
||||
* Also supports suggested expression values through a value annotation.
|
||||
* {@link AutowireCandidateResolver} implementation that matches bean definition qualifiers
|
||||
* against {@link Qualifier qualifier annotations} on the field or parameter to be autowired.
|
||||
* Also supports suggested expression values through a {@link Value value} annotation.
|
||||
*
|
||||
* <p>Also supports JSR-330's {@link javax.inject.Qualifier} annotation, if available.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
@@ -51,7 +53,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
public class QualifierAnnotationAutowireCandidateResolver implements AutowireCandidateResolver, BeanFactoryAware {
|
||||
|
||||
private final Set<Class<? extends Annotation>> qualifierTypes;
|
||||
private final Set<Class<? extends Annotation>> qualifierTypes = new LinkedHashSet<Class<? extends Annotation>>();
|
||||
|
||||
private Class<? extends Annotation> valueAnnotationType = Value.class;
|
||||
|
||||
@@ -61,10 +63,18 @@ public class QualifierAnnotationAutowireCandidateResolver implements AutowireCan
|
||||
/**
|
||||
* Create a new QualifierAnnotationAutowireCandidateResolver
|
||||
* for Spring's standard {@link Qualifier} annotation.
|
||||
* <p>Also supports JSR-330's {@link javax.inject.Qualifier} annotation, if available.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public QualifierAnnotationAutowireCandidateResolver() {
|
||||
this.qualifierTypes = new HashSet<Class<? extends Annotation>>(1);
|
||||
this.qualifierTypes.add(Qualifier.class);
|
||||
ClassLoader cl = QualifierAnnotationAutowireCandidateResolver.class.getClassLoader();
|
||||
try {
|
||||
this.qualifierTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Qualifier"));
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// JSR-330 API not available - simply skip.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +84,6 @@ public class QualifierAnnotationAutowireCandidateResolver implements AutowireCan
|
||||
*/
|
||||
public QualifierAnnotationAutowireCandidateResolver(Class<? extends Annotation> qualifierType) {
|
||||
Assert.notNull(qualifierType, "'qualifierType' must not be null");
|
||||
this.qualifierTypes = new HashSet<Class<? extends Annotation>>(1);
|
||||
this.qualifierTypes.add(qualifierType);
|
||||
}
|
||||
|
||||
@@ -85,7 +94,7 @@ public class QualifierAnnotationAutowireCandidateResolver implements AutowireCan
|
||||
*/
|
||||
public QualifierAnnotationAutowireCandidateResolver(Set<Class<? extends Annotation>> qualifierTypes) {
|
||||
Assert.notNull(qualifierTypes, "'qualifierTypes' must not be null");
|
||||
this.qualifierTypes = new HashSet<Class<? extends Annotation>>(qualifierTypes);
|
||||
this.qualifierTypes.addAll(qualifierTypes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -43,6 +43,7 @@ public interface AutowireCandidateResolver {
|
||||
* @param descriptor the descriptor for the target method parameter or field
|
||||
* @return the value suggested (typically an expression String),
|
||||
* or <code>null</code> if none found
|
||||
* @since 3.0
|
||||
*/
|
||||
Object getSuggestedValue(DependencyDescriptor descriptor);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
@@ -642,9 +643,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
|
||||
|
||||
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
|
||||
if (ObjectFactory.class.equals(descriptor.getDependencyType())) {
|
||||
if (descriptor.getDependencyType().equals(ObjectFactory.class)) {
|
||||
return new DependencyObjectFactory(descriptor, beanName);
|
||||
}
|
||||
else if (descriptor.getDependencyType().getName().equals("javax.inject.Provider")) {
|
||||
return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName);
|
||||
}
|
||||
else {
|
||||
return doResolveDependency(descriptor, descriptor.getDependencyType(), beanName, autowiredBeanNames, typeConverter);
|
||||
}
|
||||
@@ -961,4 +965,30 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializable ObjectFactory for lazy resolution of a dependency.
|
||||
*/
|
||||
private class DependencyProvider extends DependencyObjectFactory implements Provider {
|
||||
|
||||
public DependencyProvider(DependencyDescriptor descriptor, String beanName) {
|
||||
super(descriptor, beanName);
|
||||
}
|
||||
|
||||
public Object get() throws BeansException {
|
||||
return getObject();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Separate inner class for avoiding a hard dependency on the <code>javax.inject</code> API.
|
||||
*/
|
||||
private class DependencyProviderFactory {
|
||||
|
||||
public Object createDependencyProvider(DependencyDescriptor descriptor, String beanName) {
|
||||
return new DependencyProvider(descriptor, beanName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user