一. 认识·@Autowired
当我们在Spring框架中配置Bean时,常见的有三种办法:①使用xml ②使用注解 ③使用javeconfig。由于第一种方法需要在application.xml配置文件中使用大量<bean>标签来进行注入,就衍生了注解,我们只要使用@Autowired对成员变量、方法和构造函数进行标注,就可以来完成自动装配的工作, 通过 @Autowired的使用还可以消除 set ,get方法,大大减少了代码量。
eg:[使用xml配置文件注入Bean]
[使用@Autowired注解注入Bean]
@Autowired
public IAccountDao dao;
@Autowired
public IAccountService service;
二. 用法·@Autowired
@Autowired
替换:autowire属性,自动装配(默认按照类型装配,通过set方法,且方法可以省略)
位置:修饰属性,set方法
语法:@Autowired (默认为true)
@Autowired(required=false):表示忽略当前要注入的bean,如果有直接注入,没有跳过,不会报错。
@Autowired(required="true"):表示注入的时候,该bean必须存在,否则就会注入失败。
注意:1.如果容器中没有一个可以与之匹配且required属性为true则会报异常 NoSuchBeanDefinitionException
2.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配
3.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配,如果名称也没有匹配,则报异常
NoUniqueBeanDefinitionException
4.@Autowired是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Qualifier使用;
三.原理
看看源码:@Autowired 位于 org.springframework.beans.factory.annotation.Autowired包下,其实现原理就是调用了AutowiredAnnotationBeanPostProcessor类下的postProcessProperties()方法。
1.AutowiredAnnotationBeanPostProcessor是BeanPostProcesser的一个实现类它的主要功能就是对带注解的方法,set方法,和任意配置方法进行自动注入,这些注入的成员是通过注解来实现自动装配的。
在AutowiredAnnotationBeanPostProcessor类的构造方法中,我们可以看到,这些注解包括Spring的@Autowired和@Value注解,还支持JSR-330的@Inject注解(功能基本类似),这些注解都是基于AutowiredAnnotationBeanPostProcessor实现的。
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.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
} catch (ClassNotFoundException var2) {
}
}
(Bean的生命周期:实例化,属性赋值,初始化,操作使用,销毁)
AutowiredAnnotationBeanPostProcessor方法的调用,完成了扫描并处理自动注入的构造方法,之后会返回来doCreateBean方法中,所以其调用逻辑主要集中在doCreateBean()方法中,调用applyMergedBeanDefinitionPostProcessors方法,完成扫描并且注入属性和方法。
doCreateBean()主要分为三个部分,第一个部分是在实例化 Bean 的时候在 createBeanInstance 方法中会调用 AutowiredAnnotationBeanPostProcessor 中的方法来获取需要自动注入的构造方法,第二部分是调用 AutowiredAnnotationBeanPostProcessor 的方法来完成对所有需要自动注入的属性和方法的解析和缓存,最后一部分就是在 populatedBean 方法中调用到 AutowiredAnnotationBeanPostProcessor 中的方法来完成需要自动注入属性的注入工作。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
// 1.处理自动注入构造方法
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 2.扫描注解并注入
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
......
private <T> T populateBean(ResultSet rs, T bean, PropertyDescriptor[] props, int[] columnToProperty) throws SQLException {
for(int i = 1; i < columnToProperty.length; ++i) {
if (columnToProperty[i] != -1) {
PropertyDescriptor prop = props[columnToProperty[i]];
Class<?> propType = prop.getPropertyType();
Object value = null;
if (propType != null) {
value = this.processColumn(rs, i, propType);
if (value == null && propType.isPrimitive()) {
value = primitiveDefaults.get(propType);
}
}
// 存入Bean
this.callSetter(bean, prop, value);
}
}
return bean;
}