@Autowired的实现原理

1.了解@Autowired

在这之前你得了解SpringIOC容器的相关知识。

含义:@Autowired表示某个属性是否需要进行依赖注入 ,可以写在属性和方法上。注解中的required属性默认为ture,表示如果没有对象注入给属性则抛出异常

自动装配有两种实现方式:通过xml配置的方式与注解的方式。

@Autowired相比于xml配置方式

替换:autowire属性,自动装配(按照类型装配,通过set方法,且方法可以省略) 

位置:修饰属性,set方法 

语法:@Autowired(required="true") 

注意:

1.如果容器中没有一个可以与之匹配且required属性为true则会报异常  NoSuchBeanDefinitionException 

2.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配 

3.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配,如果名称也没有匹配,则报异常 NoUniqueBeanDefinitionException

2.底层实现原理:

- 位置

@Autowired的源码

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
  LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
  Class<?> targetClass = clazz;//需要处理的目标类
       
  do {
   final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();
 
            /*通过反射获取该类所有的字段,并遍历每一个字段,并通过方法findAutowiredAnnotation遍历每一个字段的所用注解,并如果用autowired修饰了,则返回auotowired相关属性*/  
 
   ReflectionUtils.doWithLocalFields(targetClass, field -> {
    AnnotationAttributes ann = findAutowiredAnnotation(field);
    if (ann != null) {//校验autowired注解是否用在了static方法上
     if (Modifier.isStatic(field.getModifiers())) {
      if (logger.isWarnEnabled()) {
       logger.warn("Autowired annotation is not supported on static fields: " + field);
      }
      return;
     }//判断是否指定了required
     boolean required = determineRequiredStatus(ann);
     currElements.add(new AutowiredFieldElement(field, required));
    }
   });
            //和上面一样的逻辑,但是是通过反射处理类的method
   ReflectionUtils.doWithLocalMethods(targetClass, method -> {
    Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
    if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
     return;
    }
    AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
    if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
     if (Modifier.isStatic(method.getModifiers())) {
      if (logger.isWarnEnabled()) {
       logger.warn("Autowired annotation is not supported on static methods: " + method);
      }
      return;
     }
     if (method.getParameterCount() == 0) {
      if (logger.isWarnEnabled()) {
       logger.warn("Autowired annotation should only be used on methods with parameters: " +
         method);
      }
     }
     boolean required = determineRequiredStatus(ann);
     PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                   currElements.add(new AutowiredMethodElement(method, required, pd));
    }
   });
    //用@Autowired修饰的注解可能不止一个,因此都加在currElements这个容器里面,一起处理  
   elements.addAll(0, currElements);
   targetClass = targetClass.getSuperclass();
  }
  while (targetClass != null && targetClass != Object.class);
 
  return new InjectionMetadata(clazz, elements);
 }

        结合注释就能看懂它做的事情了。   postProcessMergedBeanDefinition()方法的作用是找到需要自动装配的元素,构建元数据信息,然后封装到AutowiredFieledElement或AutowiredMethodElement中,然后在调用其中的inject方法,通过反射,调用容器的getBean()方法找到需要注入的Bean对象,然后注入到Bean中。

    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        InjectionMetadata metadata = this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);
        metadata.checkConfigMembers(beanDefinition);
    }

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值