AutowiredAnnotationBeanPostProcessor实现,自动装配带注释的字段,setter方法和任意配置方法
要注入的这些成员是通过Java 5注释检测的:默认情况下,Spring的@Autowired和@Value注释。
还支持JSR-330的@Inject注释(如果可用),作为Spring自己的@Autowired的直接替代品。
任何给定bean类中只有一个构造函数(最大值)可以携带此注释,并将'required'参数设置为true,表示构造函数在用作Spring bean时要自动装配。如果多个非必需构造函数带有注释,则它们将被视为自动装配的候选者。将选择具有最大数量依赖关系的构造函数,这些构造函数可以通过匹配Spring容器中的bean来满足。如果不能满足任何候选者,则将使用默认构造函数(如果存在)。带注释的构造函数不必是公共的。
在调用任何配置方法之前,在构造bean之后立即注入字段。这样的配置字段不必是公共的。
配置方法可以有任意名称和任意数量的参数;每个参数都将使用Spring容器中的匹配bean进行自动装配。 Bean属性setter方法实际上只是这种通用配置方法的一个特例。配置方法不必是公开的。
注意:默认的AutowiredAnnotationBeanPostProcessor将由“context:annotation-config”和“context:component-scan”XML标记注册。如果要指定自定义AutowiredAnnotationBeanPostProcessor bean定义,请删除或关闭默认注释配置。
注意:注释注入将在XML注入之前执行;因此后一种配置将覆盖通过两种方法连接的属性的前者。
除了上面讨论的常规注入点之外,这个后处理器还处理Spring的@Lookup注释,该注释标识了在运行时由容器替换的查找方法。
AutowiredAnnotationBeanPostProcessor里面包含3个内部类AutowiredFieldElement和AutowiredMethodElement和
ShortcutDependencyDescriptor,而AutowiredFieldElement和AutowiredMethodElement分别处理字段和方法的注解。
注入()方法被调用是在AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues方法上
内部类:AutowiredFieldElement
private class AutowiredFieldElement extends InjectedElement {
private final boolean required;
private volatile boolean cached = false;
private volatile Object cachedFieldValue;
public AutowiredFieldElement(Field field, boolean required) {
super(field, (PropertyDescriptor)null);
this.required = required;
}
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
//InjectedElem的属性之一,Member是一个接口java.lang.reflect
//class Field extends AccessibleObject implements Member
Field field = (Field)this.member;
Object value;
if (this.cached) {
value = AutowiredAnnotationBeanPostProcessor.this.resolvedCachedArgument(beanName, this.cachedFieldValue);
} else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet(1);
TypeConverter typeConverter = AutowiredAnnotationBeanPostProcessor.this.beanFactory.getTypeConverter();
try {
//通过BeanFactory的resolveDependency()方法解决依赖的值。也就是这个参数需要注入的值
value = AutowiredAnnotationBeanPostProcessor.this.beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
} catch (BeansException var12) {
throw new UnsatisfiedDependencyException((String)null, beanName, new InjectionPoint(field), var12);
}
synchronized(this) {
if (!this.cached) {//没有缓存
if (value == null && !this.required) {
this.cachedFieldValue = null;
} else {
this.cachedFieldValue = desc;
AutowiredAnnotationBeanPostProcessor.this.registerDependentBeans(beanName, autowiredBeanNames);//依赖注入
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = (String)autowiredBeanNames.iterator().next();
//对字段类型进行匹配
if (AutowiredAnnotationBeanPostProcessor.this.beanFactory.containsBean(autowiredBeanName) && AutowiredAnnotationBeanPostProcessor.this.beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new AutowiredAnnotationBeanPostProcessor.ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType());
}
}
}
this.cached = true;
}
}
}
if (value != null) {
//这里就是通过反射设置参数可见性,然后把值设置到该参数上
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
AutowiredAnnotationBeanPostProcessor类的其他内容
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet();
private String requiredParameterName = "required";
private boolean requiredParameterValue = true;
private int order = 2147483645;
private ConfigurableListableBeanFactory beanFactory;
private final Set<String> lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap(256));
private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = new ConcurrentHashMap(256);
private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap(256);
//把注解加进set集合中
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add(ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
this.logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
} catch (ClassNotFoundException var2) {
}
}
//先清空在重新装进set
public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) {
Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
this.autowiredAnnotationTypes.clear();
this.autowiredAnnotationTypes.add(autowiredAnnotationType);
}
public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> autowiredAnnotationTypes) {
Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty");
this.autowiredAnnotationTypes.clear();
this.autowiredAnnotationTypes.addAll(autowiredAnnotationTypes);
}
public void setRequiredParameterName(String requiredParameterName) {
this.requiredParameterName = requiredParameterName;
}
public void setRequiredParameterValue(boolean requiredParameterValue) {
this.requiredParameterValue = requiredParameterValue;
}
public void setOrder(int order) {
this.order = order;
}
public int getOrder() {
return this.order;
}
//设置beanfactory
public void setBeanFactory(BeanFactory beanFactory) {
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException("AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory);
} else {
this.beanFactory = (ConfigurableListableBeanFactory)beanFactory;
}
}
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);
metadata.checkConfigMembers(beanDefinition);
}
}
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeanCreationException {
if (!this.lookupMethodsChecked.contains(beanName)) {
try {
ReflectionUtils.doWithMethods(beanClass, new MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Lookup lookup = (Lookup)method.getAnnotation(Lookup.class);
if (lookup != null) {
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition)AutowiredAnnotationBeanPostProcessor.this.beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
} catch (NoSuchBeanDefinitionException var5) {
throw new BeanCreationException(beanName, "Cannot apply @Lookup to beans without corresponding bean definition");
}
}
}
});
} catch (IllegalStateException var19) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", var19);
} catch (NoClassDefFoundError var20) {
throw new BeanCreationException(beanName, "Failed to introspect bean class [" + beanClass.getName() + "] for lookup method metadata: could not find class that it depends on", var20);
}
this.lookupMethodsChecked.add(beanName);
}
Constructor<?>[] candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
synchronized(this.candidateConstructorsCache) {
candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor[] rawCandidates;
try {
rawCandidates = beanClass.getDeclaredConstructors();
} catch (Throwable var18) {
throw new BeanCreationException(beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", var18);
}
List<Constructor<?>> candidates = new ArrayList(rawCandidates.length);
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
Constructor[] var9 = rawCandidates;
int var10 = rawCandidates.length;
for(int var11 = 0; var11 < var10; ++var11) {
Constructor<?> candidate = var9[var11];
AnnotationAttributes ann = this.findAutowiredAnnotation(candidate);
if (ann == null) {
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = this.findAutowiredAnnotation(superCtor);
} catch (NoSuchMethodException var17) {
}
}
}
if (ann != null) {
if (requiredConstructor != null) {
throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + candidate + ". Found constructor with 'required' Autowired annotation already: " + requiredConstructor);
}
boolean required = this.determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName, "Invalid autowire-marked constructors: " + candidates + ". Found constructor with 'required' Autowired annotation: " + candidate);
}
requiredConstructor = candidate;
}
candidates.add(candidate);
} else if (candidate.getParameterTypes().length == 0) {
defaultConstructor = candidate;
}
}
if (!candidates.isEmpty()) {
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
} else if (candidates.size() == 1 && this.logger.isWarnEnabled()) {
this.logger.warn("Inconsistent constructor declaration on bean with name '" + beanName + "': single autowire-marked constructor flagged as optional - this constructor is effectively required since there is no default constructor to fall back to: " + candidates.get(0));
}
}
candidateConstructors = (Constructor[])candidates.toArray(new Constructor[candidates.size()]);
} else if (rawCandidates.length == 1 && rawCandidates[0].getParameterTypes().length > 0) {
candidateConstructors = new Constructor[]{rawCandidates[0]};
} else {
candidateConstructors = new Constructor[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
return candidateConstructors.length > 0 ? candidateConstructors : null;
}
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
return pvs;
} catch (BeanCreationException var7) {
throw var7;
} catch (Throwable var8) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var8);
}
}
public void processInjection(Object bean) throws BeanCreationException {
Class<?> clazz = bean.getClass();
InjectionMetadata metadata = this.findAutowiringMetadata(clazz.getName(), clazz, (PropertyValues)null);
try {
metadata.inject(bean, (String)null, (PropertyValues)null);
} catch (BeanCreationException var5) {
throw var5;
} catch (Throwable var6) {
throw new BeanCreationException("Injection of autowired dependencies failed for class [" + clazz + "]", var6);
}
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
String cacheKey = StringUtils.hasLength(beanName) ? beanName : clazz.getName();
InjectionMetadata metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized(this.injectionMetadataCache) {
metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
try {
metadata = this.buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
} catch (NoClassDefFoundError var9) {
throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() + "] for autowiring metadata: could not find class that it depends on", var9);
}
}
}
}
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
LinkedList<InjectedElement> elements = new LinkedList();
Class targetClass = clazz;
do {
final LinkedList<InjectedElement> currElements = new LinkedList();
ReflectionUtils.doWithLocalFields(targetClass, new FieldCallback() {
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
//调用findAutowiredAnnotation 找到需要注入的属性,然后在装配
AnnotationAttributes ann = AutowiredAnnotationBeanPostProcessor.this.findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (AutowiredAnnotationBeanPostProcessor.this.logger.isWarnEnabled()) {
AutowiredAnnotationBeanPostProcessor.this.logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = AutowiredAnnotationBeanPostProcessor.this.determineRequiredStatus(ann);
currElements.add(AutowiredAnnotationBeanPostProcessor.this.new AutowiredFieldElement(field, required));
}
}
});
ReflectionUtils.doWithLocalMethods(targetClass, new MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
AnnotationAttributes ann = AutowiredAnnotationBeanPostProcessor.this.findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (AutowiredAnnotationBeanPostProcessor.this.logger.isWarnEnabled()) {
AutowiredAnnotationBeanPostProcessor.this.logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterTypes().length == 0 && AutowiredAnnotationBeanPostProcessor.this.logger.isWarnEnabled()) {
AutowiredAnnotationBeanPostProcessor.this.logger.warn("Autowired annotation should only be used on methods with parameters: " + method);
}
boolean required = AutowiredAnnotationBeanPostProcessor.this.determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(AutowiredAnnotationBeanPostProcessor.this.new AutowiredMethodElement(method, required, pd));
}
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
} while(targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
if (ao.getAnnotations().length > 0) {
Iterator var2 = this.autowiredAnnotationTypes.iterator();
while(var2.hasNext()) {
Class<? extends Annotation> type = (Class)var2.next();
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
if (attributes != null) {
return attributes;
}
}
}
return null;
}
protected boolean determineRequiredStatus(AnnotationAttributes ann) {
return !ann.containsKey(this.requiredParameterName) || this.requiredParameterValue == ann.getBoolean(this.requiredParameterName);
}
protected <T> Map<String, T> findAutowireCandidates(Class<T> type) throws BeansException {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory configured - override the getBeanOfType method or specify the 'beanFactory' property");
} else {
return BeanFactoryUtils.beansOfTypeIncludingAncestors(this.beanFactory, type);
}
}
//向autowiredBeanNames注入beanname的bean对象
private void registerDependentBeans(String beanName, Set<String> autowiredBeanNames) {
if (beanName != null) {
Iterator var3 = autowiredBeanNames.iterator();
while(var3.hasNext()) {
String autowiredBeanName = (String)var3.next();
if (this.beanFactory.containsBean(autowiredBeanName)) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Autowiring by type from bean name '" + beanName + "' to bean named '" + autowiredBeanName + "'");
}
}
}
}
private Object resolvedCachedArgument(String beanName, Object cachedArgument) {
if (cachedArgument instanceof DependencyDescriptor) {
DependencyDescriptor descriptor = (DependencyDescriptor)cachedArgument;
return this.beanFactory.resolveDependency(descriptor, beanName, (Set)null, (TypeConverter)null);
} else {
return cachedArgument;
}
}