DI,也就是依赖注入,在容器中建立的 bean (对象)与 bean 之间是有依赖关系的,如果直接把对象存在 IoC 容器中,那么就都是一个独立的对象,通过建立他们的依赖关系,才能拿出一个对象,然后与它建立依赖关系的对象就也可以使用,在 Spring 的 IoC 容器中,通过配置可以明确各个 Bean之间的依赖关系当一个 Bean 需要另一个 Bean 时,IoC 容器会自动将依赖的 Bean 注入进来,这个过程就是依赖注入。
属性注入直接通过@Autowired来实现的,直接加在属性上就可以完成注入
@Controller
public class UserController {
@Autowired
private UserService userService;
public void say(){
System.out.println("UserController");
userService.say();
}
}
构造方法注入是通过在类的构造方法中完成注入
@Controller
public class UserController {
private UserService userService;
private UserController(UserService userService) {
this.userService = userService;
}
public void say() {
System.out.println("UserController");
userService.say();
}
}如果说有多个构造方法的话,就需要指明需要使用哪个构造方法完成注入

为什么会空指针呢

如果有多个构造方法的话,默认是使用无参的构造方法的,可以通过@Autowired来指明使用哪个构造方法完成注入
@Controller
public class UserController {
private UserService userService;
private UserController(){
}
@Autowired
private UserController(UserService userService) {
this.userService = userService;
}
public void say() {
System.out.println("UserController");
userService.say();
}
}关于传参:

交给 Spring 管理的对象,如果有参数,可以自己指定参数,如果没有指定,Spring 就会根据名称或者类型,从容器中查找对象,并注入进来
setter 注入是需要在 set 方法上加上@Autowired的,不能省略
@Autowired
private void setUserService(UserService userService){
this.userService = userService;
}属性注入:
优点:简洁,使用方便
缺点:不能注入一个 final 修饰的属性

构造方法注入:
优点:
setter 注入:
优点:方便在类实例之后,重新对该对象进行配置或者注入
缺点:
Autowired 如果是同样类型有多个名称的对象时,按照名称来注入,如果只有一个对象,就直接注入,无论名称是否能对上

来看多个对象:

可以通过@Primary来指定默认使用哪个 bean 来装配
@Primary
@Bean
public UserInfo userInfo1(){
return new UserInfo("lisi1",20);
}还可以通过@Qualifier和@Autowired配合使用来指定默认使用哪个 bean

当传入的参数也存在相同类型的对象时,也可以指定参数的默认值
@Bean
public UserInfo userInfo(@Qualifier("name1") String name3){
return new UserInfo(name3,20);
}如果不使用 @Autowired的话还可以使用 @Resource注解来指定

@Autowired和@Resource的区别:
UserService类,需要注入一个UserRepository,如果使用@Resource注解并且指定了一个名称(如@Resource(name = "userRepo")),Spring 会首先查找名称为userRepo的UserRepository类型的 Bean。只有在找不到这个名称对应的 Bean 时,才会去查找类型为UserRepository的 Bean,而不管其名称是什么。@Autowired 的装配顺序:
