DI
依赖注⼊是⼀个过程,是指IoC容器在创建Bean时, 去提供运⾏时所依赖的资源,⽽资源指的就是对象.我们使⽤ @Autowired 这个注解,完成了依赖注⼊的操作.简单来说, 就是把对象取出来放到某个类的属性中
关于依赖注⼊, Spring也给我们提供了三种⽅式:
- 属性注⼊(Field Injection)
- 构造⽅法注⼊(Constructor Injection)
- Setter 注⼊(Setter Injection)
构造器注入
1.构造器注入
java
//创建一个水杯类
class Cup{
public void holdCup(){
System.out.println("水杯装水");
}
}
//人喝水,构造器注入
class Person{
private Cup cup;
//构造器注入依赖
public Person(Cup cup){
this.cup=cup;
}
public void drinkWater(){
cup.holdCup();
System.out.println("人喝水");
}
}
Setter方法注入
java
class Person {
private Cup cup;
// Setter方法注入
public void setCup(Cup cup) {
this.cup = cup;
}
public void drinkWater() {
cup.holdWater();
System.out.println("喝水");
}
}
*属性注入(重点)
通过@Autowired,将Service层类注入Controller类中
java
@Service
public class UserService {
public void method(){
System.out.println("启动UserService类");
}
}
java
@Controller
public class UserController {
@Autowired
private UserService service;
public void method(){
System.out.println("启动UserController类");
service.method();
}
}

@Autowired存在问题
当同⼀类型存在多个bean时, 使⽤@Autowired会存在问题
java
@Data
@Component
class User{
private String userName;
private Integer age;
}
@Component
public class Autowired {
@Bean
public User uesr1(){
User user=new User();
user.setUserName("zhangsan");
user.setAge(18);
return user;
}
@Bean
public User user2(){
User user=new User();
user.setUserName("lisi");
user.setAge(20);
return user;
}
}
java
@Controller
public class UserController {
@Autowired
private UserService service;
@Autowired
private User user;
public void method(){
System.out.println("启动UserController类");
service.method();
System.out.println(user);
}
}

Spring提供了以下⼏种解决⽅案:
• @Primary
• @Qualifier
• @Resource
• @Primary:

• @Qualifier:
• @Resource
@Autowird 与 @Resource的区别:
• @Autowired 是spring框架提供的注解,⽽@Resource是JDK提供的注解
• @Autowired 默认是按照类型注⼊,⽽@Resource是按照名称注⼊. 相⽐@Autowired 来说,@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean.
总结:
属性注⼊
◦ 优点: 简洁,使⽤⽅便;
◦ 缺点:▪ 只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指针异常)
▪ 不能注⼊⼀个Final修饰的属性
• 构造函数注⼊(Spring 4.X推荐)
◦ 优点:
▪ 可以注⼊final修饰的属性
▪ 注⼊的对象不会被修改
▪ 依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法是在类加载阶段就会执⾏的⽅法.
▪ 通⽤性好, 构造⽅法是JDK⽀持的, 所以更换任何框架,他都是适⽤的
◦ 缺点:
▪ 注⼊多个对象时, 代码会⽐较繁琐
• Setter注⼊(Spring 3.X推荐)
◦ 优点: ⽅便在类实例之后, 重新对该对象进⾏配置或者注⼊
◦ 缺点:
▪ 不能注⼊⼀个Final修饰的属性
▪ 注⼊对象可能会被改变, 因为setter⽅法可能会被多次调⽤, 就有被修改的⻛险