Bean有几种注入方式?它们有什么区别?
Bean有三种注入方式,属性注入,setter注入,构造方法注入。
1.属性注入
优点:属性注入最大的优点就是实现简单、使用简单。只需要给变量添加一个@AutoWried注释,就可以在不new对象的情况下,直接获得注入对象。
缺点:1.无法注入一个不可变的对象(final修饰)2.只能适应于IOC容器,Idea也会提醒不建议使用。
2.Setter注入
Setter注入的实现代码如下:
@RestController
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
@RequestMapping("/add")
public UserInfo add(@RequestParam String username, @RequestParam String password) {
return userService.add(username, password);
}
}
优点:它符合单一职责的设计原则(一个类应该只负责一项职责或一个功能),因为每一个Setter只针对一个对象。
缺点:不能注入不可变的对象(final修饰),因为Setter方法注入是在对象已经创建之后再调用的,它试图为不可变对象赋值,会导致编译错误;注入的对象可以调用多次,也就是注入对象会被修改。
3.构造方法注入
实现代码如下
@RestController
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping("/add")
public UserInfo add(@RequestParam String username, @RequestParam String password) {
return userService.add(username, password);
}
}
如果当前的类只有一个构造方法,那么@Autowired有也可以省略,如:
@RestController
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping("/add")
public UserInfo add(@RequestParam String username, @RequestParam String password) {
return userService.add(username, password);
}
}
优点:
1.注入不可变对象:使用构造方法可以注入不可变对象,如下代码:
2.注入对象不会被修改:构造方法不会像Setter注入那样,构造方法在对象创建只会执行一次,因此它不存在注入对象被随时(调用)修改的情况。
3.完全初始化:因为依赖对象是在构造方法中执行的,而构造方法是在对象创建之初执行的,因此被注入的对象在使用之前,会被完全初始化。
4.通用性更好:构造注入和属性注入不同,构造方法注入可适用于任何环境,无论是IOC框架还是非IOC框架,构造方法注入的代码都是通用的。
缺点:不如属性注入简单。