supplier接口的get()方法本身不延迟加载,延迟与否取决于具体实现:若get()中直接new对象则每次新建;若加判空缓存则实现懒且单例;若执行io操作则真正延迟到首次调用。

Supplier 接口的 get() 方法本身不延迟加载,它只是定义了一个“获取对象”的契约;真正实现延迟加载,靠的是你如何实现或使用这个 Supplier。
延迟加载的本质是“用时才创建”
Supplier 不会自动帮你延迟——它只是一个函数式接口,只规定了有一个无参、返回泛型结果的 get() 方法。延迟与否,取决于你在 lambda 或实现类里写什么逻辑:
- 如果
get()里直接 new 一个对象,那每次调用都新建,是“懒但不缓存” - 如果
get()里先判断是否已创建,未创建再初始化并缓存,那就是“懒且单例”(即典型的延迟+单次初始化) - 如果
get()里读配置、查数据库、开网络连接,那这些耗时操作就真的被推迟到第一次调用时才执行
常见延迟加载写法示例
✅ 懒加载 + 单次初始化(推荐用于重量级对象):
private final Supplier<connection> connectionSupplier = new Supplier() {
private Connection instance;
@Override
public Connection get() {
if (instance == null) {
instance = createExpensiveConnection(); // 真正耗时操作
}
return instance;
}
};</connection>
等价的 lambda 写法(需配合局部变量或外部状态,实际中常用静态内部类或 AtomicReference):
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
AtomicReference<connection> ref = new AtomicReference();
Supplier<connection> lazyConn = () -> {
Connection c = ref.get();
if (c == null) {
c = createExpensiveConnection();
ref.set(c);
}
return c;
};</connection></connection>
和 Spring @Lazy、@Bean 的关系
Spring 的 @Lazy 注解作用在 Bean 创建阶段,控制 IOC 容器是否延迟实例化该 Bean;而 Supplier 的延迟发生在代码调用层面。两者可结合:
- 用
@Bean返回一个 Supplier,把真正对象的创建逻辑封装进去 - 把 Supplier 注入后,由业务代码决定何时调用
get(),从而实现更细粒度的延迟 - 注意:Spring 默认对
Supplier<t></t>类型 Bean 是“懒解析”的——即注入的 Supplier 本身轻量,get()才触发目标 Bean 获取(若该 Bean 也是 @Lazy,则进一步延迟)
别踩坑:Supplier 不等于自动缓存
下面这种写法是**非延迟**的(对象在 Supplier 创建时就生成了):
Connection conn = createExpensiveConnection(); // ⚠️ 立刻执行! Supplier<connection> badSupplier = () -> conn; // 只是包装已有引用</connection>
还有这种是**每次都新建**(有延迟,但无复用):
Supplier<connection> alwaysNew = () -> createExpensiveConnection(); // ✅ 延迟,❌ 不复用</connection>
是否需要复用,得根据场景判断:比如每次 HTTP 调用需要新 Client,那就该每次都 new;如果是全局配置对象,那就该只初始化一次。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










