当前位置: 代码网 > it编程>编程语言>Java > SpringBoot中依赖注入的常用方式对比详解

SpringBoot中依赖注入的常用方式对比详解

2026年07月26日 Java 我要评论
依赖注入(dependency injection,di)是 spring 框架的核心特性之一,也是实现 ioc(控制反转)的具体方式。spring 提供了多种依赖注入方式,每种方式各有优劣。本文系统

依赖注入(dependency injection,di)是 spring 框架的核心特性之一,也是实现 ioc(控制反转)的具体方式。spring 提供了多种依赖注入方式,每种方式各有优劣。本文系统讲解构造器注入、字段注入、setter 注入、方法注入的用法与区别,并涵盖 @autowired@resource 的差异、循环依赖问题、最佳实践等内容。

一、依赖注入的基本概念

1.1 什么是依赖注入

依赖注入是指对象不再自行创建其依赖项,而是由容器(spring ioc 容器)在运行时将依赖项注入到对象中。

传统方式(手动创建依赖):controller ──new──→ service ──new──→ repository,对象自己控制依赖的创建,耦合度高

依赖注入(容器管理依赖):

  • container ──注入──→ controller
  • container ──注入──→ service
  • container ──注入──→ repository

容器统一管理对象的创建和装配,对象只声明需要的依赖

1.2 依赖注入的三个角色

角色说明示例
依赖者需要其他组件的对象usercontroller
依赖项被需要的组件userservice
注入者负责将依赖项注入依赖者spring ioc 容器

1.3 spring 依赖注入方式总览

注入方式注解 / 配置特点
构造器注入构造方法 + @autowired(可省略)官方推荐,不可变,可保证完全初始化
字段注入@autowired 标注在字段上简洁,但不推荐
setter 注入@autowired 标注在 setter 方法上可选依赖,可重新注入
方法注入@autowired 标注在普通方法上灵活,可注入多个依赖
lookup 方法注入@lookup解决单例注入原型的问题

二、构造器注入

2.1 基本用法

通过构造方法将依赖传入类中。spring 4.3+ 如果类只有一个构造方法,@autowired 可以省略。

import org.springframework.stereotype.service;

/**
 * 订单服务
 */
@service
public class orderservice {

    private final userservice userservice;
    private final orderrepository orderrepository;

    /**
     * 构造器注入(spring 4.3+ 单构造方法可省略 @autowired)
     */
    public orderservice(userservice userservice, orderrepository orderrepository) {
        this.userservice = userservice;
        this.orderrepository = orderrepository;
    }

    public void createorder(long userid) {
        // 使用注入的依赖
        userservice.getuser(userid);
        orderrepository.save(null);
    }
}

2.2 结合 lombok 简化

实际项目中最常见的写法,使用 @requiredargsconstructor 自动生成构造方法:

import lombok.requiredargsconstructor;
import lombok.extern.slf4j.slf4j;
import org.springframework.stereotype.service;

/**
 * 订单服务
 */
@slf4j
@service
@requiredargsconstructor
public class orderservice {

    private final userservice userservice;           // final 字段
    private final orderrepository orderrepository;   // final 字段

    public void createorder(long userid) {
        userservice.getuser(userid);
        orderrepository.save(null);
    }
}

关键@requiredargsconstructor 只为 final 字段和 @nonnull 标注的字段生成构造方法。非 final 字段不会包含在构造方法中。

2.3 多构造方法场景

当类有多个构造方法时,必须用 @autowired 指定主构造方法:

@service
public class orderservice {

    private final userservice userservice;
    private final orderrepository orderrepository;
    private final logservice logservice;  // 可选依赖

    /**
     * 主构造方法(spring 使用此构造方法实例化)
     */
    @autowired
    public orderservice(userservice userservice, orderrepository orderrepository) {
        this.userservice = userservice;
        this.orderrepository = orderrepository;
        this.logservice = null;
    }

    /**
     * 辅助构造方法(不参与 spring 注入)
     */
    public orderservice(userservice userservice, orderrepository orderrepository,
                        logservice logservice) {
        this.userservice = userservice;
        this.orderrepository = orderrepository;
        this.logservice = logservice;
    }
}

2.4 优缺点

优点缺点
依赖不可变(final 字段),线程安全依赖较多时构造方法参数过多
对象创建即完全初始化,不会出现 npe无法注入循环依赖(但这本身是好事)
易于单元测试(可直接 new 传入 mock)需要配合 lombok 减少样板代码
明确声明所有必需依赖
spring 官方推荐

三、字段注入

3.1 基本用法

直接在字段上标注 @autowired,spring 通过反射注入依赖:

import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.service;

/**
 * 订单服务(字段注入 - 不推荐)
 */
@service
public class orderservice {

    @autowired
    private userservice userservice;

    @autowired
    private orderrepository orderrepository;

    public void createorder(long userid) {
        userservice.getuser(userid);
        orderrepository.save(null);
    }
}

3.2 优缺点

优点缺点
代码简洁,最少样板代码无法使用 final,依赖可变,不安全
不需要构造方法或 setter单元测试困难(无法通过构造方法传入 mock)
隐藏了依赖关系(类表面看不到依赖)
违反单一职责(加依赖太容易,容易过度膨胀)
依赖注入发生在对象创建之后,可能存在半初始化状态
spring 官方不推荐

spring 官方建议:从 spring 4.0 开始,官方文档明确推荐构造器注入,不推荐字段注入。

3.3 为什么字段注入仍被广泛使用

尽管不推荐,字段注入在实际项目中仍很常见,原因:

  • 代码量少,开发效率高
  • 早期 spring 教程普遍使用字段注入
  • 依赖较少时,缺点不明显

但这是技术债务,建议在新项目中避免使用。

四、setter 注入

4.1 基本用法

通过 setter 方法注入依赖:

import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.service;

/**
 * 订单服务(setter 注入)
 */
@service
public class orderservice {

    private userservice userservice;
    private orderrepository orderrepository;

    @autowired
    public void setuserservice(userservice userservice) {
        this.userservice = userservice;
    }

    @autowired
    public void setorderrepository(orderrepository orderrepository) {
        this.orderrepository = orderrepository;
    }

    public void createorder(long userid) {
        userservice.getuser(userid);
        orderrepository.save(null);
    }
}

4.2 可选依赖

通过 required = false 标记可选依赖,当容器中找不到对应 bean 时不报错:

@autowired(required = false)
public void setlogservice(logservice logservice) {
    this.logservice = logservice;
}

注意:构造器注入不支持 required = false。如果需要可选依赖,必须使用 setter 注入。

4.3 优缺点

优点缺点
支持可选依赖(required = false依赖可变(非 final),不保证不变性
可以在对象创建后重新注入(热替换)对象可能处于未完全初始化状态
单元测试方便(可调用 setter 传入 mock)代码量比字段注入多
解决循环依赖(与构造器注入配合)

五、方法注入

5.1 基本用法

在任意方法上标注 @autowired,可以一次注入多个依赖:

import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.service;

/**
 * 订单服务(方法注入)
 */
@service
public class orderservice {

    private userservice userservice;
    private orderrepository orderrepository;

    @autowired
    public void configuredependencies(userservice userservice, orderrepository orderrepository) {
        this.userservice = userservice;
        this.orderrepository = orderrepository;
    }

    public void createorder(long userid) {
        userservice.getuser(userid);
        orderrepository.save(null);
    }
}

5.2 优缺点

优点缺点
灵活,可一次注入多个依赖不如构造器注入清晰
方法名可自定义,语义更灵活使用场景少
可以在方法中添加初始化逻辑

使用场景:较少使用,通常构造器注入或 setter 注入已足够。适合需要同时设置多个相关依赖并执行初始化逻辑的场景。

六、@autowired 与 @resource 的区别

@autowired@resource 都用于依赖注入,但来源和行为不同。

6.1 基本对比

特性@autowired@resource
来源spring(org.springframework.beans.factory.annotationjsr-250 标准(jakarta.annotation
默认匹配方式按类型(bytype)按名称(byname)
找不到时的行为required = false 可设为可选无法设为可选,找不到直接报错
配合注解@qualifier 指定 bean 名称name 属性直接指定
适用位置构造器、字段、setter、方法字段、setter(不支持构造器)
框架依赖仅 spring标准 jsr-250,其他框架也支持

6.2 @autowired 匹配流程

@autowired
private userservice userservice;

匹配流程:

1. 按类型查找 userservice 的 bean

2. 找到唯一 → 注入 ✅

3. 找到多个 → 按字段名 "userservice" 匹配 bean 名称

4. 仍不唯一 → 报错 nouniquebeandefinitionexception

5. 配合 @qualifier("beanname") → 按指定名称注入

示例:

// 多个实现类场景
public interface paymentservice {
    void pay(string orderid);
}

@service("alipayservice")
public class alipayserviceimpl implements paymentservice {
    @override
    public void pay(string orderid) {
        system.out.println("支付宝支付: " + orderid);
    }
}

@service("wechatpayservice")
public class wechatpayserviceimpl implements paymentservice {
    @override
    public void pay(string orderid) {
        system.out.println("微信支付: " + orderid);
    }
}

多实现场景的注入方式:

// 方式1:@autowired + @qualifier(按名称指定)
@autowired
@qualifier("alipayservice")
private paymentservice paymentservice;

// 方式2:字段名与 bean 名称一致(spring 自动匹配)
@autowired
private paymentservice alipayservice;  // 字段名 "alipayservice" 匹配 bean 名称

// 方式3:@primary 标注默认实现
@service
@primary  // 多个实现时,@autowired 优先注入标注了 @primary 的
public class alipayserviceimpl implements paymentservice { }

6.3 @resource 匹配流程

@resource
private userservice userservice;

匹配流程:

1. 如果指定了 name → 只按名称查找

2. 如果未指定 name → 先按字段名 "userservice" 查找

3. 找不到 → 再按类型查找

4. 仍找不到 → 报错 nosuchbeandefinitionexception

示例:

// 方式1:默认按字段名匹配
@resource
private paymentservice alipayservice;  // 按名称 "alipayservice" 查找

// 方式2:指定 name
@resource(name = "wechatpayservice")
private paymentservice paymentservice;

// 方式3:指定 type
@resource(type = alipayserviceimpl.class)
private paymentservice paymentservice;

6.4 选型建议

场景推荐
spring 项目,构造器注入@autowired@resource 不支持构造器)
需要按名称注入@autowired + @qualifier
跨框架兼容@resource(jsr-250 标准)
简单项目均可,团队统一即可

spring 官方推荐:优先使用 @autowired,构造器注入时 @autowired 可省略。

七、@autowired 的 required 属性

7.1 必需依赖 vs 可选依赖

// 必需依赖(默认 required = true)
// 容器中找不到对应 bean 会启动失败
@autowired
private userservice userservice;

// 可选依赖(required = false)
// 容器中找不到对应 bean 不报错,注入 null
@autowired(required = false)
private logservice logservice;

7.2 各注入方式对 required 的支持

注入方式支持 required = false说明
构造器注入不支持构造方法参数始终是必需的
字段注入支持@autowired(required = false)
setter 注入支持@autowired(required = false)
方法注入支持@autowired(required = false)

7.3 optional 替代方案

java 8+ 推荐用 optional 声明可选依赖,语义更清晰:

import java.util.optional;

@service
public class orderservice {

    private final userservice userservice;
    private final optional<logservice> logservice;

    public orderservice(userservice userservice, optional<logservice> logservice) {
        this.userservice = userservice;
        this.logservice = logservice;
    }

    public void createorder(long userid) {
        userservice.getuser(userid);
        // 使用前判断是否存在
        logservice.ifpresent(service -> service.log("创建订单: " + userid));
    }
}

注意optional 只能用于构造器注入和 setter 注入,不能用于字段注入。

八、循环依赖问题

8.1 什么是循环依赖

两个或多个 bean 互相依赖,形成闭环:

a 依赖 b,b 依赖 a → 循环依赖

@service
class a {
    @autowired 
    b b;  // a 需要 b
}

@service
class b {
    @autowired 
    a a;  // b 需要 a
}

8.2 spring 如何解决循环依赖

spring 通过三级缓存机制解决 setter/字段注入的循环依赖:

缓存级别名称存储内容
一级缓存singletonobjects完全初始化好的 bean(成品)
二级缓存earlysingletonobjects提前暴露的半成品 bean(已实例化,未注入依赖)
三级缓存singletonfactoriesbean 工厂(objectfactory,用于生成半成品)

解决循环依赖的流程(a 依赖 b,b 依赖 a):

1. 创建 a:实例化 a → 将 a 的工厂放入三级缓存
2. 注入 a 的依赖 b → 创建 b
3. 创建 b:实例化 b → 将 b 的工厂放入三级缓存
4. 注入 b 的依赖 a → 查找 a
   → 一级缓存没有
   → 二级缓存没有
   → 三级缓存有 a 的工厂 → 生成 a 的半成品 → 放入二级缓存 → 删除三级缓存
5. b 拿到 a 的半成品 → b 注入完成 → b 放入一级缓存
6. a 拿到 b → a 注入完成 → a 放入一级缓存

8.3 构造器注入的循环依赖

构造器注入的循环依赖无法解决!

  • a 的构造方法需要 b → 创建 b
  • b 的构造方法需要 a → 创建 a
  • a 的构造方法需要 b → ... 死循环

spring 会抛出:beancurrentlyincreationexception

8.4 各注入方式的循环依赖支持

注入方式是否支持循环依赖说明
构造器注入❌ 不支持无法实例化任何一方,直接报错
字段注入✅ 支持通过三级缓存解决
setter 注入✅ 支持通过三级缓存解决
方法注入✅ 支持通过三级缓存解决

关键理解:构造器注入不支持循环依赖,这其实是优点而非缺点。循环依赖通常意味着设计有问题,构造器注入强制你面对并解决它。

8.5 循环依赖的解决方案

方案说明适用场景
重构消除循环提取公共逻辑到第三个类首选方案
改为 setter 注入将其中一方改为 setter 注入临时方案,不推荐长期保留
使用 @lazy延迟注入代理对象临时方案
事件机制解耦用事件代替直接调用适合通知类场景

@lazy 方案:

@service
public class orderservice {

    private final userservice userservice;

    // @lazy 注入代理对象,首次使用时才真正初始化
    public orderservice(@lazy userservice userservice) {
        this.userservice = userservice;
    }
}

九、lookup 方法注入

9.1 问题场景

单例 bean 注入原型 bean 时,原型 bean 只在注入时创建一次,之后不再创建新的:

@service
public class orderservice {

    // 希望每次使用都是新的实例,但实际只创建了一次
    @autowired
    private prototypebean prototypebean;  // 始终是同一个对象 ❌
}

@scope("prototype")
@component
public class prototypebean {
    // 原型作用域,应该每次获取都创建新实例
}

9.2 解决方案:@lookup

import org.springframework.beans.factory.annotation.lookup;
import org.springframework.stereotype.service;

/**
 * 订单服务
 */
@service
public abstract class orderservice {

    /**
     * lookup 方法注入:每次调用都返回新的 prototypebean 实例
     * spring 通过 cglib 动态子类化重写此方法
     */
    @lookup
    protected abstract prototypebean getprototypebean();

    public void processorder(string orderid) {
        // 每次调用 getprototypebean() 都返回新实例
        prototypebean bean = getprototypebean();
        bean.dosomething(orderid);
    }
}

注意@lookup 标注的方法必须是抽象方法(或返回值与 bean 类型匹配的具体方法),spring 通过 cglib 生成子类重写该方法。因此类不能是 final,方法也不能是 final/private

9.3 替代方案:objectfactory

如果不想用抽象类,可以用 objectfactory

import org.springframework.beans.factory.objectprovider;
import org.springframework.stereotype.service;

@service
public class orderservice {

    private final objectprovider<prototypebean> prototypebeanprovider;

    public orderservice(objectprovider<prototypebean> prototypebeanprovider) {
        this.prototypebeanprovider = prototypebeanprovider;
    }

    public void processorder(string orderid) {
        // 每次调用 getobject() 都返回新实例
        prototypebean bean = prototypebeanprovider.getobject();
        bean.dosomething(orderid);
    }
}

优势objectprovider 是构造器注入友好的方案,不需要抽象类,推荐使用。

十、泛型注入

spring 支持泛型类型的依赖注入,通过类型参数自动匹配对应实现。

10.1 泛型基类

/**
 * 通用 repository 基类
 * @param <t> 实体类型
 */
public abstract class baserepository<t> {
    public abstract t findbyid(long id);
    public abstract void save(t entity);
}

10.2 具体实现

import org.springframework.stereotype.repository;

@repository
public class userrepository extends baserepository<user> {
    @override
    public user findbyid(long id) {
        return new user(id, "张三");
    }

    @override
    public void save(user entity) {
        system.out.println("保存用户: " + entity);
    }
}

@repository
public class orderrepository extends baserepository<order> {
    @override
    public order findbyid(long id) {
        return new order(id, 100.0);
    }

    @override
    public void save(order entity) {
        system.out.println("保存订单: " + entity);
    }
}

10.3 泛型 service 注入

import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.service;

/**
 * 通用 service 基类
 * spring 根据泛型参数自动匹配对应的 repository
 */
public abstract class baseservice<t> {

    protected baserepository<t> repository;

    @autowired
    public void setrepository(baserepository<t> repository) {
        this.repository = repository;
    }

    public t getbyid(long id) {
        return repository.findbyid(id);
    }

    public void save(t entity) {
        repository.save(entity);
    }
}
@service
public class userservice extends baseservice<user> {
    // spring 自动注入 userrepository(因为 baserepository<user> 匹配 userrepository)
}

@service
public class orderservice extends baseservice<order> {
    // spring 自动注入 orderrepository(因为 baserepository<order> 匹配 orderrepository)
}

使用:

@autowired
private userservice userservice;

userservice.getbyid(1l);     // 调用 userrepository.findbyid()
userservice.save(new user()); // 调用 userrepository.save()

优势:泛型注入实现了代码复用,避免了为每个实体重复编写 crud 方法。

十一、bean 生命周期回调与注入

11.1 注入时机

bean 生命周期中的注入时机:

1. 实例化(instantiation)       → 构造方法调用
2. 属性填充(population)        → 依赖注入发生在此阶段
3. 初始化(initialization)
   ├── @postconstruct           → 注入完成后执行
   ├── initializingbean.afterpropertiesset()
   └── @bean(initmethod=...)    
4. 使用(in use)
5. 销毁(destruction)
   ├── @predestroy
   ├── disposablebean.destroy()
   └── @bean(destroymethod=...)

11.2 @postconstruct 中使用注入的依赖

import jakarta.annotation.postconstruct;
import jakarta.annotation.predestroy;
import org.springframework.stereotype.service;

/**
 * 订单服务
 */
@service
public class orderservice {

    private final userservice userservice;

    public orderservice(userservice userservice) {
        this.userservice = userservice;
        // ⚠️ 此时依赖已注入,但如果通过字段注入则可能还未注入
        system.out.println("1. 构造方法");
    }

    @postconstruct
    public void init() {
        // ✅ 所有依赖已注入完毕,可以安全使用
        system.out.println("2. @postconstruct: 依赖已就绪");
        userservice.warmupcache();
    }

    @predestroy
    public void cleanup() {
        system.out.println("3. @predestroy: 清理资源");
    }
}

关键@postconstruct 在所有依赖注入完成后执行,是执行初始化逻辑的安全位置。不要在构造方法中调用被注入的依赖的方法(字段注入场景下依赖可能还未注入)。

十二、四种注入方式横向对比

12.1 全面对比

维度构造器注入字段注入setter 注入方法注入
不可变性final
完全初始化保证
单元测试便利性✅ 可直接 new❌ 需反射✅ 可 setter✅ 可调用方法
可选依赖
循环依赖❌ 不支持✅ 支持✅ 支持✅ 支持
代码简洁度⭐⭐⭐(lombok)⭐⭐⭐⭐⭐⭐⭐⭐
依赖可见性✅ 构造方法明确❌ 隐藏⭐ setter 明确⭐ 方法明确
spring 官方推荐✅ 强烈推荐❌ 不推荐⭐ 可选依赖时使用⭐ 特殊场景
违反单一职责感知✅ 参数过多有警示❌ 加字段太容易⭐ 中等⭐ 中等

12.2 适用场景

场景推荐方式理由
必需依赖构造器注入保证不可变和完全初始化
可选依赖setter 注入required = false
简单工具类字段注入(可接受)代码简洁,但仅限非核心逻辑
需要多个相关依赖同时设置方法注入可在方法中添加初始化逻辑
单例注入原型objectprovider / @lookup每次获取新实例
通用泛型基类泛型注入代码复用
配置类 @bean 方法方法参数注入spring 自动从容器中查找

12.3 @bean 方法中的注入

@configuration 类中,@bean 方法的参数会自动从容器中注入:

import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;

@configuration
public class appconfig {

    /**
     * 参数 userservice 自动从容器中注入
     * 无需标注 @autowired(spring 4.3+ 自动注入)
     */
    @bean
    public orderservice orderservice(userservice userservice, orderrepository orderrepository) {
        return new orderservice(userservice, orderrepository);
    }
}

十三、最佳实践

13.1 项目中的注入规范

import lombok.requiredargsconstructor;
import lombok.extern.slf4j.slf4j;
import org.springframework.stereotype.service;

/**
 * 订单服务 - 推荐写法示范
 */
@slf4j
@service
@requiredargsconstructor
public class orderservice {

    // ✅ 必需依赖:final + 构造器注入(lombok 生成构造方法)
    private final userservice userservice;
    private final orderrepository orderrepository;

    // ✅ 可选依赖:objectprovider(构造器友好)
    private final objectprovider<logservice> logserviceprovider;

    /**
     * 创建订单
     */
    public void createorder(long userid, ordercreaterequest request) {
        // 使用必需依赖
        user user = userservice.getbyid(userid);

        // 使用可选依赖
        logserviceprovider.ifavailable(service -> 
            service.log("创建订单: userid=" + userid)
        );

        // 业务逻辑
        order order = new order();
        order.setuserid(userid);
        order.setamount(request.getamount());
        orderrepository.save(order);
    }
}

13.2 最佳实践清单

编号实践说明
1构造器注入优先所有必需依赖用构造器注入,配合 @requiredargsconstructor
2字段加 final保证依赖不可变,线程安全
3避免字段注入除非是遗留代码或快速原型
4可选依赖用 objectprovider@autowired(required = false) 语义更清晰
5多实现用 @qualifier明确指定 bean 名称,避免歧义
6接口编程注入接口类型,而非实现类
7避免循环依赖构造器注入天然避免,如遇循环则重构
8不在构造方法中调用依赖方法字段注入场景下依赖可能未就绪
9初始化逻辑放 @postconstruct此时所有依赖已注入
10团队统一风格全部用构造器注入 + lombok,保持一致性

13.3 单元测试对比

构造器注入的测试便利性:

import org.junit.jupiter.api.test;
import org.junit.jupiter.api.extension.extendwith;
import org.mockito.mock;
import org.mockito.junit.jupiter.mockitoextension;

import static org.mockito.mockito.*;

/**
 * 构造器注入 → 单元测试极简
 */
@extendwith(mockitoextension.class)
class orderservicetest {

    @mock
    private userservice userservice;

    @mock
    private orderrepository orderrepository;

    @test
    void testcreateorder() {
        // 直接 new 传入 mock,无需 spring 容器
        orderservice orderservice = new orderservice(userservice, orderrepository);

        when(userservice.getbyid(1l)).thenreturn(new user(1l, "张三"));

        orderservice.createorder(1l, new ordercreaterequest());

        verify(orderrepository, times(1)).save(any());
    }
}

字段注入的测试困难:

/**
 * 字段注入 → 单元测试困难
 * 需要反射或 spring testcontext 才能注入 mock
 */
class orderservicefieldinjectiontest {

    @test
    void testcreateorder() throws exception {
        orderservice service = new orderservice();

        // 需要通过反射注入私有字段(非常 hacky)
        field field = orderservice.class.getdeclaredfield("userservice");
        field.setaccessible(true);
        field.set(service, mock(userservice.class));

        // ... 测试逻辑
    }
}

十四、总结

14.1 核心要点速查

  1. 构造器注入是官方推荐:不可变、完全初始化、测试友好
  2. 字段注入不推荐:隐藏依赖、不可变、测试困难
  3. setter 注入用于可选依赖required = falseobjectprovider
  4. @autowired 按类型匹配,配合 @qualifier 按名称指定
  5. @resource 按名称匹配,jsr-250 标准,不支持构造器
  6. 多实现场景@primary 指定默认 + @qualifier 精确指定
  7. 构造器注入不支持循环依赖:这是优点,强制解决设计问题
  8. spring 三级缓存解决 setter/字段注入的循环依赖
  9. 单例注入原型用 objectprovider@lookup
  10. 泛型注入实现代码复用baserepository<t> 自动匹配实现
  11. @postconstruct 是初始化逻辑的安全位置
  12. lombok @requiredargsconstructor 简化构造器注入

14.2 决策树

依赖是否必需?
  ├── 必需 → 构造器注入(final + @requiredargsconstructor)
  └── 可选 → objectprovider(构造器友好)
            或 setter 注入(@autowired(required = false))
是否有多个实现?
  ├── 是 → @primary 指定默认 + @qualifier 精确指定
  └── 否 → 直接注入
是否是单例注入原型?
  ├── 是 → objectprovider 或 @lookup
  └── 否 → 正常注入
是否遇到循环依赖?
  ├── 是 → 重构消除循环(首选)
  │        或 @lazy 延迟注入(临时)
  └── 否 → 正常注入

以上就是springboot中依赖注入的常用方式对比详解的详细内容,更多关于springboot依赖注入的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com