一. 认识·@Autowired
当我们在Spring框架中配置Bean时,常见的有三种办法:①使用xml ②使用注解 ③使用javeconfig。由于第一种方法需要在application.xml配置文件中使用大量
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 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;
- }