Spring IoC——依赖注入

1. 依赖注入的介绍

DI,也就是依赖注入,在容器中建立的 bean (对象)与 bean 之间是有依赖关系的,如果直接把对象存在 IoC 容器中,那么就都是一个独立的对象,通过建立他们的依赖关系,才能拿出一个对象,然后与它建立依赖关系的对象就也可以使用,在 Spring 的 IoC 容器中,通过配置可以明确各个 Bean之间的依赖关系当一个 Bean 需要另一个 Bean 时,IoC 容器会自动将依赖的 Bean 注入进来,这个过程就是依赖注入。

2. 三种注入方式

2.1. 属性注入

属性注入直接通过@Autowired来实现的,直接加在属性上就可以完成注入

java 复制代码
@Controller
public class UserController {
    @Autowired
    private UserService userService;
    public void say(){
        System.out.println("UserController");
        userService.say();
    }
}

2.2. 构造方法注入

构造方法注入是通过在类的构造方法中完成注入

java 复制代码
@Controller
public class UserController {
    private UserService userService;

    private UserController(UserService userService) {
        this.userService = userService;
    }

    public void say() {
        System.out.println("UserController");
        userService.say();
    }
}

如果说有多个构造方法的话,就需要指明需要使用哪个构造方法完成注入

为什么会空指针呢

如果有多个构造方法的话,默认是使用无参的构造方法的,可以通过@Autowired来指明使用哪个构造方法完成注入

java 复制代码
@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 就会根据名称或者类型,从容器中查找对象,并注入进来

2.3. setter 注入

setter 注入是需要在 set 方法上加上@Autowired的,不能省略

java 复制代码
@Autowired
private void setUserService(UserService userService){
    this.userService = userService;
}

2.4. 三种方式的对比

属性注入:

优点:简洁,使用方便

缺点:不能注入一个 final 修饰的属性

构造方法注入:

优点:

  1. 可以注入 final 修饰的属性
  2. 注入的对象不会被修改
  3. 依赖对象在使用前一定会被初始化,构造方法是在类加载时就会执行的
  4. 通用性好,构造方法是 JDK 支持的,换任何框架都适用

setter 注入:

优点:方便在类实例之后,重新对该对象进行配置或者注入

缺点:

  1. 不能注入 final 修饰的属性
  2. 注入的对象可能会被改变,因为 setter 方法可能会被多次调用,就会有被修改的风险

3. @Autowired 存在的问题

Autowired 如果是同样类型有多个名称的对象时,按照名称来注入,如果只有一个对象,就直接注入,无论名称是否能对上

来看多个对象:

可以通过@Primary来指定默认使用哪个 bean 来装配

java 复制代码
@Primary
@Bean
public UserInfo userInfo1(){
    return new UserInfo("lisi1",20);
}

还可以通过@Qualifier@Autowired配合使用来指定默认使用哪个 bean

当传入的参数也存在相同类型的对象时,也可以指定参数的默认值

java 复制代码
@Bean
public UserInfo userInfo(@Qualifier("name1") String name3){
    return new UserInfo(name3,20);
}

如果不使用 @Autowired的话还可以使用 @Resource注解来指定

@Autowired@Resource的区别:

  1. @Autowired 是Spring 框架提供的注解,@Resource 是 JDK 提供的注解
  2. @Autowired 默认是按照类型注入,@Resource 默认是按照名称注入
  3. @Autowired 优先按照类型匹配,如果类型相同再看名称,@Resource 前提也是要类型匹配,只不过是名称匹配的优先级更高 :例如,有一个UserService类,需要注入一个UserRepository,如果使用@Resource注解并且指定了一个名称(如@Resource(name = "userRepo")),Spring 会首先查找名称为userRepoUserRepository类型的 Bean。只有在找不到这个名称对应的 Bean 时,才会去查找类型为UserRepository的 Bean,而不管其名称是什么。

@Autowired 的装配顺序:

我的主页

相关推荐
落尘2984 分钟前
Bean 的作用域和生命周期
后端
是店小二呀5 分钟前
处理Linux下磁盘空间不足问题的实用指南
后端
落尘2986 分钟前
如何通过 JWT 来解决登录认证问题
后端
是店小二呀7 分钟前
处理Linux下内存泄漏问题的诊断与解决方法
后端
倚栏听风雨13 分钟前
IDEA 插件开发 对文件夹下的类进行 语法检查
后端
CHQIUU16 分钟前
跨语言哈希一致性:C# 与 Java 的 MD5 之战?
java·c#·哈希算法
郝同学的测开笔记18 分钟前
云原生探索系列(十七):Go 语言sync.Cond
后端·云原生·go
uhakadotcom19 分钟前
持续写作的“农耕思维”:如何像农民一样播种,收获稳定成长与收入
后端·面试·github
JavaDog程序狗28 分钟前
【java】easypoi导出excel单元格,填充动态下拉列
java·spring boot·excel
Java中文社群36 分钟前
国内首个「混合推理模型」Qwen3深夜开源,盘点它的N种对接方式!
java·人工智能·后端