文章目录
- 4.3 DI详解
- 4.3.1属性注入
- 4.3.2 构造方法注入
- 4.3.3 Setter注入
- 4.3.4 三种注入优缺点
- 4.4 `@Autowired` 存在问题
- @Primary
- @Qualifier
4.3 DI详解
依赖注入是一个过程,是指Ioc容器在创建Bean的时候,去提供运行时所依赖的资源(对象)
简单来说,就是将对象取出来放到某个类的属性中
4.3.1属性注入
属性注入是通过@Autowired
实现的
@Service
public class UserService {
public void sayHello() {
System.out.println("hello UserService");
}
}
@Controller
public class UserController {
@Autowired
private UserService userService;
public void sayHello() {
System.out.println("hello UserController");
userService.sayHello();
}
}
@SpringBootApplication
public class Je20240721Application {
public static void main(String[] args) {
//获取Spring上下文
ApplicationContext context = SpringApplication.run(Je20240721Application.class, args);
//从Spring上下文中获取对象
UserController userController = context.getBean(UserController.class);
userController.sayHello();
}
}
运行结果:
4.3.2 构造方法注入
构造方法注入是在类的构造方法中实现注入
@Controller
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
public void sayHello() {
System.out.println("hello UserController");
userService.sayHello();
}
}
此时,如果类中只有一个构造方法,那么@Autowired
可以省略
4.3.3 Setter注入
@Controller
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public void sayHello() {
System.out.println("hello UserController");
userService.sayHello();
}
}
4.3.4 三种注入优缺点
- 属性注入:
- 优点:简洁,使用方便
- 缺点:只能用于Ioc容器;不能注入一个final修饰的属性
- 构造方法注入
- 优点:可以注入一个final修饰的属性;注入的对象不会被修改;依赖对象在使用前一定会被初始化;通用性好,构造方法是JDK支持的,所以换任何框架都是适用的
- 缺点:注入多个对象时,代码比较繁琐;
- Setter注入
- 优点:方便在类实例之后,重新对该类进行配置或注入
- 缺点:不能注入一个final修饰的属性;对象有被修改的风险
4.4 @Autowired
存在问题
当同一个对象存在多个bean的时候,使用@Autowired
会存在问题
@Component
public class BeanConfig {
@Bean("u1")
public UserInfo userInfo1() {
UserInfo u = new UserInfo();
u.setUserName("zhangsan");
u.setPassword("123456");
return u;
}
@Bean
public UserInfo userInfo2() {
UserInfo u = new UserInfo();
u.setUserName("lisi");
u.setPassword("123456");
return u;
}
}
@Controller
public class UserController {
@Autowired
private UserInfo userInfo;
}
有以下几种解决方案:
@Primary
当存在多个相同类型的bean注入的时候,加上@Primary注解,来确定默认的实现
@Qualifier
指定要注入的bean对象,在@Qualifier
的value属性中注入,指定注入的bean的名称@Qualifier
不能单独使用,必须搭配@Autowired
使用
(3)@Resource
按照bean的名称进行注入,通过name属性指定要注入的bean的名称
@Autowired
和@Resource
的区别:
@Autowired
是spring框架提供的注解,而@Resource
是JDK提供的注解;
@Autowired
默认通过类型注入,而@Resource
默认按照名称注入
@Autowired
装配顺序