当前位置:首页 > 科技  > 软件

终于有人把Autowired注解讲清楚了,赞!!!

来源: 责编: 时间:2024-04-02 17:21:37 295观看
导读@Autowired是什么@Autowired 注解由 Spring 的 org.springframework.beans.factory.annotation.Autowired 类定义, 直译过来就是自动注入的意思。@Autowired的定义如下:@Target({ElementType.CONSTRUCTOR, ElementType

@Autowired是什么

@Autowired 注解由 Spring 的 org.springframework.beans.factory.annotation.Autowired 类定义, 直译过来就是自动注入的意思。C0X28资讯网——每日最新资讯28at.com

@Autowired的定义如下:C0X28资讯网——每日最新资讯28at.com

@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Autowired {    boolean required() default true;}

@Autowired 的使用场景

1.字段注入

将 @Autowired 直接应用于类的成员变量上。Spring 容器会自动为这些变量找到与其类型匹配的 Bean 实例,并进行注入。C0X28资讯网——每日最新资讯28at.com

public class MyClass {    @Autowired    private MyService myService;}

2.构造器注入

将 @Autowired 应用于类的构造函数上。C0X28资讯网——每日最新资讯28at.com

Spring 容器会自动解析构造函数的参数类型,并为这些参数找到与其类型匹配的 Bean 实例,然后注入到构造函数中。C0X28资讯网——每日最新资讯28at.com

public class MyClass {    private MyService myService;        @Autowired    public MyClass(MyService myService) {        this.myService = myService;    }}

3.方法注入

将 @Autowired 应用于类的方法上。C0X28资讯网——每日最新资讯28at.com

当类实例化时,Spring 容器会自动解析这些方法的参数类型,并为这些参数找到与其类型匹配的 Bean 实例,然后调用这些方法并注入参数。C0X28资讯网——每日最新资讯28at.com

public class MyClass {    private MyService myService;    @Autowired    public void setMyService(MyService myService) {        this.myService = myService;    }}

需要注意的是,通过 @Autowired 注解实现依赖注入时,如果在 Spring 容器中找不到与某个依赖类型匹配的 Bean 实例(或者找到多个,但没有明确的优先级),那么 Spring 将抛出异常。C0X28资讯网——每日最新资讯28at.com

除非将该注解的 required 属性设置为 false,这样在找不到匹配的 Bean 时,框架将不会抛出异常。C0X28资讯网——每日最新资讯28at.com

public class MyClass {    @Autowired(required = false)    private MyService myService;}

@Autowired是如何工作的

在 Spring 中,AutowiredAnnotationBeanPostProcessor (AABP) 负责处理带有 @Autowired 注解的成员变量、Setter 方法。C0X28资讯网——每日最新资讯28at.com

以下是 AABP 解析 @Autowired 的完整代码调用流程:C0X28资讯网——每日最新资讯28at.com

当 Spring 容器实例化一个 Bean 时,会创建相应的 BeanDefinition 对象。BeanDefinition 包含了关于 Bean 的所有元数据信息。C0X28资讯网——每日最新资讯28at.com

在容器实例化、配置和初始化 Bean 的过程中,它会调用 AABP 的 postProcessMergedBeanDefinition 方法,以收集与依赖注入相关的元数据。C0X28资讯网——每日最新资讯28at.com

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {  InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);  try {   metadata.inject(bean, beanName, pvs);  }  catch (BeanCreationException ex) {   throw ex;  }  catch (Throwable ex) {   throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);  }  return pvs; }

findAutowiringMetadata 方法会查找 Bean 的所有@Autowired 注解相关的元数据,并获取 InjectionMetadata 对象, 如果该对象尚不存在,会创建一个新的对象。C0X28资讯网——每日最新资讯28at.com

protected InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {    // ... (省略无关代码)    List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();    Class<?> targetClass = clazz;    // 遍历 Bean 的类结构,从子类向基类查找有@Autowired 注解的字段、方法和构造器    do {        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();        ReflectionUtils.doWithLocalFields(targetClass, field -> {            // 寻找带有@Autowired 注解的字段            MergedAnnotation<?> ann = findAutowiredAnnotation(field);            if (ann != null) {                if (Modifier.isStatic(field.getModifiers())) {                    // 静态字段不能自动注入                    // ... (省略错误处理和日志)                }                boolean required = determineRequiredStatus(ann);                // AutowiredFieldElement 属性Autowired元素                currElements.add(new AutowiredFieldElement(field, required));            }        });        ReflectionUtils.doWithLocalMethods(targetClass, method -> {            // 寻找带有@Autowired 注解的Setter方法或普通方法            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {                return;            }            MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);            if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {                if (Modifier.isStatic(method.getModifiers())) {                    // 静态方法不能自动注入                    // ... (省略错误处理和日志)                }                PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);                boolean required = determineRequiredStatus(ann);                // AutowiredMethodElement 方法 Autowired 元素                currElements.add(new AutowiredMethodElement(method, required, pd));            }        });        elements.addAll(0, currElements);        targetClass = targetClass.getSuperclass();    }    while (targetClass != null && targetClass != Object.class);    // 构建并返回 InjectionMetadata 对象    return new InjectionMetadata(clazz, elements);}

上面的代码中,我在关键位置添加了注释,老铁们可以仔细看一下,上述代码的主要作用就是找到一个类中:C0X28资讯网——每日最新资讯28at.com

  • 添加了@Autowired的属性信息,用 AutowiredFieldElement进行表示。
  • 添加了 @Autowired 的方法信息,用AutowiredMethodElement进行表示。

当依赖注入需要发生时,容器会调用 AABP 的 postProcessProperties 方法。C0X28资讯网——每日最新资讯28at.com

该方法中会调用 InjectionMetadata 的 inject 方法来实际注入 @Autowired 注解的成员变量、成员方法:C0X28资讯网——每日最新资讯28at.com

metadata.inject(bean, beanName, pvs);

最后,通过执行 AutowiredFieldElement 和 AutowiredMethodElement 的 inject 方法来实际注入属性值和方法参数。C0X28资讯网——每日最新资讯28at.com

AutowiredFieldElement 的 inject 方法实现如下:C0X28资讯网——每日最新资讯28at.com

@Override  protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {   Field field = (Field) this.member;   Object value;   if (this.cached) {    try {     value = resolvedCachedArgument(beanName, this.cachedFieldValue);    }    catch (NoSuchBeanDefinitionException ex) {     // Unexpected removal of target bean for cached argument -> re-resolve     value = resolveFieldValue(field, bean, beanName);    }   }   else {    value = resolveFieldValue(field, bean, beanName);   }   if (value != null) {    ReflectionUtils.makeAccessible(field);    field.set(bean, value);   }  }

AutowiredMethodElement 的 inject 方法的实现如下:C0X28资讯网——每日最新资讯28at.com

@Override  protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {   if (checkPropertySkipping(pvs)) {    return;   }   Method method = (Method) this.member;   Object[] arguments;   if (this.cached) {    try {     arguments = resolveCachedArguments(beanName);    }    catch (NoSuchBeanDefinitionException ex) {     // Unexpected removal of target bean for cached argument -> re-resolve     arguments = resolveMethodArguments(method, bean, beanName);    }   }   else {    arguments = resolveMethodArguments(method, bean, beanName);   }   if (arguments != null) {    try {     ReflectionUtils.makeAccessible(method);     method.invoke(bean, arguments);    }    catch (InvocationTargetException ex) {     throw ex.getTargetException();    }   }  }

通过以上流程,AutowiredAnnotationBeanPostProcessor 将解析并注入带有 @Autowired 注解的成员变量、方法。C0X28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-80864-0.html终于有人把Autowired注解讲清楚了,赞!!!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 超火前端框架:公开叫板 Vue、React,拥有 5k star

下一篇: 可伸缩架构案例:数据太多,如何无限扩展你的数据库?

标签:
  • 热门焦点
  • 卢伟冰长文解析K60至尊版 对Redmi有着里程碑式的意义

    在今天的Redmi后性能时代战略发布会结束之后,Redmi总经理卢伟冰又带来了一篇长文,详解了为什么 Redmi 要开启后性能时代?为什么选择和 MediaTek、Pixelworks 深度合作?以及后性
  • 红魔电竞平板评测:大屏幕硬实力

    前言:三年的疫情因为要上网课的原因激活了平板市场,如今网课的时代已经过去,大家的生活都恢复到了正轨,这也就意味着,真正考验平板电脑生存的环境来了。也就是面对着这种残酷的
  • 天猫精灵Sound Pro体验:智能音箱没有音质?来听听我的

    这几年除了手机作为智能生活终端最主要的核心之外,第二个可以成为中心点的产品是什么?——是智能音箱。 手机在执行命令的时候有两种操作方式,手和智能语音助手,而智能音箱只
  • 5月安卓手机好评榜:魅族20 Pro夺冠

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年5月1日至5月31日,仅限国内市场。第一名:魅族20 Pro好评率:97.50%不得不感慨魅族老品牌还
  • 每天一道面试题-CPU伪共享

    前言:了不起:又到了每天一到面试题的时候了!学弟,最近学习的怎么样啊 了不起学弟:最近学习的还不错,每天都在学习,每天都在进步! 了不起:那你最近学习的什么呢? 了不起学弟:最近在学习C
  • 得物宠物生意「狂飙」,发力“它经济”

    作者|花花小萌主近日,得物宣布正式上线宠物鉴别,通过得物App内的&ldquo;在线鉴别&rdquo;,可找到鉴别宠物的选项。通过上传自家宠物的部位细节,就能收获拥有专业资质认证的得物鉴
  • 网红炒股不为了赚钱,那就是耍流氓!

    来源:首席商业评论6月26日高调宣布入市,网络名嘴大v胡锡进居然进军了股市。在一次财经媒体峰会上,几个财经圈媒体大佬就&ldquo;胡锡进炒股是否知道认真报道&rdquo;展开讨论。有
  • 苹果、三星、惠普等暂停向印度出口笔记本和平板电脑

    集微网消息,据彭博社报道,在8月3日印度突然禁止在没有许可证的情况下向印度进口电脑/平板及显示器等产品后,苹果、三星电子和惠普等大公司暂停向印度
  • 自研Exynos回归!三星Galaxy S24系列将提供Exynos和骁龙双版本

    年初,全新的三星Galaxy S23系列发布,包含Galaxy S23、Galaxy S23+和Galaxy S23 Ultra三个版本,全系搭载超频版骁龙8 Gen 2,虽同样采用台积电4nm工艺制
Top