Spring中的依赖注入

一、常用的依赖注入方式有三种:

1、属性注入:基于注解@Autowired的依赖注入 (不推荐)
2.1 、构造器的依赖注入(推荐)
2.2 、构造器的依赖注入-lombok升级版(推荐)
3、setter注入(不推荐)

二、详细介绍
2.1 @Autowired的使用

例如:在构造器中使用到了@Autowired,因为构造器先执行,@Autowired后执行,所以此时是null

@RestController
@RequestMapping("/api/{edition}/page")
public class MyPageHelperController2 {

    @Autowired
    private UserService userService;
    
    private String school;


    public MyPageHelperController2(){
        this.school = userService.getSchool();
    }
}

解决方案1:将初始化操作后移。

    @Autowired
    private UserService userService;

    public MyPageHelperController2() {
         //userService.getSchool();
    }
    
    @PostConstruct //该注解标注的方法,会在构造函数、依赖注入之后执行,所以正确
    public void init() {
        userService.getSchool();
    }
}

解决方案2:使用构造器注入

2.2.1 构造器注入(推荐)

@RestController
@RequestMapping("/api/{edition}/page2")
public class MyPageHelperController2 {

    private UserService userService;

    @Autowired
    public MyPageHelperController2(UserService userService){
        this.userService = userService;
    }
}

在创建MyPageHelperController2对象的时候,通过参数形式,强制依赖UserService对象,确保创建MyPageHelperController2对象时每个对象都是有效状态。

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

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

	private final AService aService;
}

2.3 setter注入(不推荐)

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

Spring Bean的三种依赖注入实现方式Spring可通过三种方式实现依赖注入

  • 基于构造函数的依赖注入
  • 基于Setter方法的依赖注入
  • 以及基于Field的依赖注入

基于构造函数的依赖注入@Component
public class DemoBean{
public final DependencyBean dependencyBean;

public DemoBean(DependencyBean dependencyBean) {
    this.dependencyBean = dependencyBean;
}

}基于构造函数注入的优点是,可以很方便地构造immutable的对象,将注入的字段声明为 final,在类实例化期间注入依赖。基于Setter方法的依赖注入@Component
public class DemoBean{
public DependencyBean dependencyBean;

@Autowired
public void setDependencyBean(DependencyBean dependencyBean) {
    this.dependencyBean = dependencyBean;
}

}基于Setter方法注入的优点是,可以在实例Bean构造完成后注入,或者重新注入Bean,其中一个应用场景是通过JMX MBean进行管理。基于Field的依赖注入@Component
public class DemoBean{
@Autowired
private DependencyBean dependencyBean;
}Spring Framework官方已经不推荐这种依赖注入方法,文档中也去掉了相关的使用说明,编译器也会给出警告 Field injection is not recommended,究其原因,使用Field依赖注入时,有一些弊端:相比基于构造函数的依赖注入方式,基于Field的依赖注入无法构造immutable对象,因为如果将dependencyBean声明为final,则必须在构造函数中初始化。对单元测试不友好,如果没有对外的set接口,则很难替换mock bean

如何选择?
Spring官方推荐使用基于构造函数的依赖注入方式,结合final,可以构建immutable的对象,能够保证所有的依赖都不会为null。而当需要在实例Bean构造完成后注入,或者重新注入Bean时,选择使用Setter方法的注入方式。除此之外,当在Bean中使用模版方法,在Abstract类中注入依赖时,需要使用Setter方法注入。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值