@Autowired注入、构造器注入、setter注入的使用方式?区别?

三种注入方式的使用

1、@Autowired注入(不推荐)

spring官方不推荐使用这种方式,同时idea会给我们发出警告:Field injection is not recommended

@RestController
@RequestMapping("/test")
public class TestController {
 
    @Autowired
    private AService aService;
    @Autowired
    private BService bService;
 
}

2.1、构造器注入(推荐)

spring在4.x版本后就推荐使用构造器的方式的来注入fileld

@RestController
@RequestMapping("/test")
public class TestController {
 
    private final AService aService;
    private final BService bService;
 
    // Spring4.3+之后,constructor注入支持非显示注入方式。
    // @Autowired
    public DictController(AService aService,
                          BService bService) {
        this.aService = aService;
        this.aService = aService;
    }
}

2.2、构造器注入-lombok升级版(推荐)

@RequiredArgsConstructor(onConstructor_ = @Autowired)

该注解是Lombok提供的注解 (可以通过该注解使用构造器注入对象,但是对象必须为final的)

@RequiredArgsConstructor(onConstructor=@_(@Autowired))
@RestController
@RequestMapping("/test")
public class TestController {

	private final AService aService;
	private final BService bService;
}

3、setter注入

@RestController
@RequestMapping("/test")
public class TestController {
 
    private final AService aService;
    private final BService bService;
 
    @Autowired
    public void setAService(AService aService){
        this.aService = aService;
    }
  
    @Autowired
    public void setBService(BService bService){
        this.bService = bService;
    }
}

循环依赖问题如何解决?

前言:
处理循环依赖有很多种方式。我们在处理循环依赖时,首先应该考虑的是是否能够通过重新设计依赖来避免循环依赖并且我们能否接受因重新设计导致的时间成本。如果成本很高或者我们确实需要循环依赖,那么可以使用下面的方式来解决循环依赖问题,推荐优先考虑使用setter方式。

1、使用@Autowired或setter注入。(都支持循环依赖)

2、构造器注入:通过懒加载注解 @Lazy 来支持循环依赖,看下面代码:

@RestController
@RequestMapping("/test")
public class TestController {
 
    private final AService aService;
    private final BService bService;
 
    // Spring4.3+之后,constructor注入支持非显示注入方式。
    // @Autowired
 
    // @Lazy 注解标注在参数上、构造函数上、字段上都是可以的
    public DictController(@Lazy AService aService,
                          @Lazy BService bService) {
        this.aService = aService;
        this.aService = aService;
    }
}
 
or
 
@RequiredArgsConstructor(onConstructor_ = {@Lazy, @Autowired})
@RestController
@RequestMapping("/test")
public class TestController {
 
    private final AService aService;
    private final BService bService;
}

注入方式的区别

@Autowired注入

在容器启动,为对象赋值的时候,遇到@Autowired注解,会用后置处理器机制,来创建属性的实例,然后再利用反射机制,将实例化好的属性,赋值给对象。

构造器注入

使用构造器能避免注入的依赖是空的情况。因为在bean的生命周期里面先执行的是bean的构造器,然后才给bean里面的属性赋值。
(一个对象所有依赖的对象先实例化后,才实例化这个对象。没有他们就没有我原则)

setter注入

使用set方法依赖注入时,Spring首先实例化对象,然后才实例化所有依赖的对象。


虽然在理论上“构造函数注入”和“set方法注入”代表两种不同的依赖强度,但是在spring中,spring并不会把无效的合作者传递给一个bean。如果合作者无效或不存在spring会抛出异常,这样spring保证一个对象的合作者都是可用的。所以在spring中,“构造函数注入”和“set方法注入”唯一的区别在于2种方式创建合作者的顺序不同。


官方推荐理由

单一职责: 当使用构造函数注入的时候,你会很容易发现参数是否过多,这个时候需要考虑你这个类的职责是否过大,考虑拆分的问题;而当使用@Autowired注入field的时候,不容易发现问题

依赖不可变: 只有使用构造函数注入才能注入final

依赖隐藏:使用依赖注入容器意味着类不再对依赖对象负责,获取依赖对象的职责就从类抽离出来,IOC容器会帮你自动装备。这意味着它应该使用更明确清晰的公用接口方法或者构造器,这种方式就能很清晰的知道类需要什么和到底是使用setter还是构造器

降低容器耦合度: 依赖注入框架的核心思想之一是托管类不应依赖于所使用的DI容器。换句话说,它应该只是一个普通的POJO,只要您将其传递给所有必需的依赖项,就可以独立地实例化。这样,您可以在单元测试中实例化它,而无需启动IOC容器并单独进行测试(使用一个可以进行集成测试的容器)。如果没有容器耦合,则可以将该类用作托管或非托管类,甚至可以切换到新的DI框架。

————————————————

  • 9
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: @Autowired 和 @Resource 都是用来将一个已经实例化的bean注入到另一个bean中的注解。 但是,@Autowired 是由 Spring 框架提供的注解,而 @Resource 是由 J2EE 提供的注解。 对于 @Autowired 注解,当你想注入一个bean时,可以通过构造器setter方法或者是一个属性来注入,并且你可以在运行时使用@Qualifier("beanName")来指定你想要注入哪一个bean。 对于 @Resource 注解,你只能在类型安全的方式(比如属性名)来注入bean。如果你想使用@Resource注解来指定一个具体的bean,你可以使用@Resource(name = "beanName")。 总的来说,如果你在使用Spring框架,那么你应该使用@Autowired注解,因为它提供了更多的功能。如果你不是在使用Spring框架,或者是为了更好地兼容J2EE规范,那么你应该使用@Resource注解。 ### 回答2: @Autowired和@Resource都是Spring框架中用于进行依赖注入的注解。它们的作用是自动将符合条件的依赖对象注入到相应的类中,从而实现类与类之间的解耦。 区别如下: 1. 来源不同:@AutowiredSpring自带的注解,而@Resource是Java标准的注解,但在Spring框架中也可以使用。 2. 自动注入方式不同:@Autowired是按照对象类型进行自动注入的,可以通过byName和byType两种方式进行匹配;而@Resource是按照对象名称进行自动注入的,只能按照byName的方式匹配。 3. 处理注解熟练度不同:@Autowired由于是Spring自带的注解,对于Spring框架的其他功能支持更加完善;而@Resource是Java标准注解,对于Spring框架的功能支持较少。 4. 注解的扩展性不同:@Autowired注解可以用于构造方法、属性、方法和参数上,而@Resource注解只能用于属性和方法上。 5. 配置参数不同:@Autowired注解没有额外的属性需要设置,而@Resource注解可以通过name属性指定注入的名称。 总结来说,@Autowired注解通常用于按照类型进行自动注入,而@Resource注解则用于按照名称进行自动注入,它们在使用方式上有所差别,但都能达到实现依赖注入的目的。 ### 回答3: @Autowired和@Resource都是用于注入依赖对象的注解,它们在功能上有一些区别。 @AutowiredSpring框架的注解,在使用时可以标注在字段、构造方法、Setter方法和一般方法上。它是根据类型进行自动装配的,会自动匹配和注入具有相同类型的Bean对象。如果容器中有多个相同类型的Bean对象,可以使用@Qualifier注解来指定具体的Bean。 @Resource是JavaEE规范提供的注解,它也可以标注在字段、构造方法、Setter方法和一般方法上。它是根据名称进行装配的,默认按照Bean的名称进行匹配和注入。如果找不到与名称匹配的Bean对象,会尝试根据类型进行匹配。同时,@Resource注解还可以通过name属性指定具体的Bean名称。 另外,@Resource注解还支持通过type属性指定Bean的类型,但这种方式只能用于指定唯一类型,无法指定具体的Bean。 总的来说,@AutowiredSpring框架的注解,注入时根据类型进行匹配;@Resource是JavaEE规范的注解,注入时首先根据名称进行匹配,如果找不到再根据类型进行匹配。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值