前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring中的@Autowired注解详细讲解

Spring中的@Autowired注解详细讲解

原创
作者头像
祁画
发布2024-07-28 16:09:11
2170
发布2024-07-28 16:09:11
举报
文章被收录于专栏:技术分享

@Autowired注解基础

@Autowired注解可以用于构造函数、setter方法、字段以及配置方法上,以指示Spring自动注入相应的bean。它的工作原理基于类型匹配,Spring容器会查找与所需类型匹配的bean,并自动注入。

字段注入

代码语言:java
复制
@Component 

public class MyComponent { 

 @Autowired 

 private MyDependency dependency; 

}

构造函数注入

在写代码时,博主推荐的做法是使用构造函数注入,因为它可以使类更易于测试,并且确保了依赖项在对象创建时就已经设置。

代码语言:java
复制
@Component 

public class MyComponent { 

 private final MyDependency dependency; 

 @Autowired 

 public MyComponent(MyDependency dependency) { 

 this.dependency = dependency; 

 } 

}

Setter方法注入

虽然setter注入不如构造函数注入受欢迎,但在某些情况下,它可能是必要的。

代码语言:java
复制
@Component 

public class MyComponent { 

 private MyDependency dependency; 

 @Autowired 

 public void setDependency(MyDependency dependency) { 

 this.dependency = dependency; 

 } 

}

解析流程与原理

当Spring容器启动时,它会扫描所有标注了@Component(或其派生注解如@Service, @Repository, @Controller等)的类,并创建相应的bean定义。**当遇到@Autowired注解时,Spring会查找匹配的bean来注入**。

匹配规则基于类型。比如,如果有一个类型为MyDependency的字段标注了@Autowired,Spring会查找类型为MyDependency的bean进行注入。**如果有多个匹配的bean,则需要使用@Qualifier注解来指定具体的bean**。

相同Bean的案例分析:多例与冲突解决

当Spring容器中存在多个相同类型的bean时,使用@Autowired可能会导致冲突。比如下面的场景:

假设我们有两个实现了同一个接口的bean:

代码语言:java
复制
@Component("firstBean") 

public class FirstBean implements MyInterface { /\*...\*/ } 

@Component("secondBean") 

public class SecondBean implements MyInterface { /\*...\*/ }

如果我们在另一个组件中尝试自动装配这个接口的实例:

代码语言:java
复制
@Component 

public class MyComponent { 

 @Autowired // 这里会发生什么? 

 private MyInterface myInterface; 

}

在这种情况下,Spring会抛出NoUniqueBeanDefinitionException,因为它不清楚应该注入哪一个实现。为了解决这个问题,我们可以使用@Qualifier注解来指定具体的bean名称:

代码语言:java
复制
@Component 

public class MyComponent { 

 @Autowired 

 @Qualifier("firstBean") // 指定要注入的bean名称 

 private MyInterface myInterface; 

}

另一种解决方法是使用Java配置或XML配置来显式声明bean的关系

@Autowired和@Resource注解的区别

这种问法也是面试官经常问到的典型问题!接下来详细介绍一下这块知识点。

首先是它们的依赖查找方式不同。

  • @Autowired默认按照类型(byType)进行自动装配的。上文提到过,**如果存在多个相同类型的bean,需要配合@Qualifier注解来指定bean的名称(byName),或者确保需要注入的字段、方法参数或构造函数参数是唯一的。**
  • @Resource默认按照名称(byName)进行装配,它会查找与指定名称相同的bean。**如果找不到匹配的bean,它会退回到按照类型(byType)进行查找**。So,@Resource可以指定名称(通过name属性)和类型(通过type属性,但通常不需要指定,因为Java编译器会推断出类型)。

同时,它们的使用方式也有所不同。

@Autowired可以标注在构造器、方法、参数、字段上,以支持构造器注入、setter注入和字段注入。

而@Resource也可以标注在字段和方法上,但通常更常见于字段注入。

对于强制依赖问题,他们的表现如下:

@Autowired有一个required属性,默认为true,表示被注入的bean是必需的。如果找不到匹配的bean,Spring容器在启动时会抛出异常。当设置为false时,如果找不到bean,则不会报错,但相关字段会被设置为null。

@Resource没有直接提供类似的属性,但可以通过Java的@Nullable注解来标明某个字段可以为null。

总结与最佳实践

博主在此做个小结,各位小伙伴们记住了哟:

  • 优先使用构造函数注入,因为它更加不可变且易于测试。
  • 当存在多个匹配的bean时,使用@Qualifier来消除歧义。
  • 尽量避免在字段上使用@Autowired,因为这会使代码更难以理解和测试;应该考虑使用构造函数或setter方法注入。

文章到这里就先结束了,感兴趣的可以订阅专栏哈,后续会继续分享相关的知识点。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • @Autowired注解基础
    • 字段注入
      • 构造函数注入
        • Setter方法注入
        • 解析流程与原理
        • 相同Bean的案例分析:多例与冲突解决
        • @Autowired和@Resource注解的区别
        • 总结与最佳实践
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档