在Spring 2.5 引入了 @Autowired 注解,@Autowired可以标注在属性上、方法上和构造器上,来完成自动装配。在启动spring 时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowiedt时,就会在IOC容器自动查找需要的bean,并装配给该对象的属性。仅有一个required参数,默认为true。
当标注的属性是接口时,其实注入的是这个接口的实现类, 如果这个接口有多个实现类,只要使用@Autowired就会报错,因为它默认是根据类型找,然后就会找到多个实现类bean,不知道要注入哪个。然后它就会根据属性名去找。如果查询的结果为空,那么会抛出异常。所以如果有多个实现类的话可以使用@Qualifier(value=“类名”),根据名称查找。
源码:
package org.springframework.beans.factory.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
boolean required() default true;
}
spring对 @Autowired 注解的实现逻辑就在 AutowiredAnnotationBeanPostProcessor实现的
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);
metadata.checkConfigMembers(beanDefinition);
}
postProcessMergedBeanDefinition()方法的作用是找到需要自动装配的元素,构建元数据信息,然后封装到AutowiredFieledElement或AutowiredMethodElement中,然后在调用其中的inject方法,通过反射,调用容器的getBean()方法找到需要注入的Bean对象,然后注入到Bean中。
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
if (!this.checkPropertySkipping(pvs)) {
Method method = (Method)this.member;
Object[] arguments;
if (this.cached) {
try {
arguments = this.resolveCachedArguments(beanName);
} catch (NoSuchBeanDefinitionException var8) {
arguments = this.resolveMethodArguments(method, bean, beanName);
}
} else {
arguments = this.resolveMethodArguments(method, bean, beanName);
}
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
} catch (InvocationTargetException var7) {
throw var7.getTargetException();
}
}
}
}