Spring中@Autowired的工作原理

在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();
                    }
                }

            }
        }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值