函数式接口是延迟行为的契约载体,Supplier<T>作为Bean定义的工厂签名实现按需创建;Function<ApplicationContext,T>支持带依赖的延迟构造;@Lazy注解可自动包装为Supplier;自定义接口默认方法可统一增强生命周期逻辑。

函数式接口本身不是 Bean,也不能直接当 Bean 实例延迟创建——但它可以作为“延迟行为的契约载体”,在自研 IOC 容器中充当工厂骨架的核心抽象。关键不在于让函数式接口自己被延迟实例化,而是用它来封装**延迟执行的创建逻辑**,并配合容器的懒加载机制实现按需构造。
把 Supplier 当作延迟 Bean 的创建契约
最直接的方式是将 Supplier<T> 作为 Bean 定义的底层工厂签名。它天然表达“需要时才调用 get() 得到 T”的语义,与 lazy-init 行为高度契合:
- 注册 Bean 时,不立即 new 实例,而是保存一个
Supplier<User> userSupplier = () -> new User("Alice") - 容器内部维护一个
Map<String, Supplier<?>>或BeanDefinition中持有该 Supplier 字段 - 首次
getBean("user")时,才触发supplier.get(),完成真实对象创建和依赖注入
用 Function + 参数上下文支持带依赖的延迟构造
纯 Supplier 无法注入其他 Bean。若目标 Bean 构造需依赖已存在的组件(如 DataSource、Config),可升级为 Function<ApplicationContext, T>:
- 注册时存入
(ctx) -> new UserService(ctx.getBean(UserDao.class)) - getBean 时传入当前容器引用,由函数自行解析依赖并组装
- 避免提前初始化 UserDao,仅在 UserService 首次获取时才拉取其依赖
结合 @Lazy 语义,让函数式接口成为配置入口
自研容器可模仿 Spring 的 @Lazy 设计,在解析注解或 XML 时识别延迟标记,并自动包装为函数式工厂:
立即学习“Java免费学习笔记(深入)”;
- 遇到
@Lazy class OrderService { ... },不生成普通 BeanDefinition,而生成Supplier<OrderService>类型定义 - 扫描阶段只注册契约,不触发 newInstance;运行时通过反射+Lambda 生成 Supplier 实例
- 这样既保持 API 简洁(用户写 @Lazy),底层又统一走函数式调度路径
默认方法增强:给延迟工厂加生命周期钩子
自定义函数式接口可添加 default 方法,统一处理延迟场景下的横切逻辑:
- 例如
interface LazyBeanFactory<T> extends Supplier<T> { default T getWithLog() { log("Creating bean..."); return get(); } } - 容器调用
factory.getWithLog()替代 rawget(),无需修改每个 Supplier 实现 - 还可集成缓存、异常重试、指标上报等通用能力,所有延迟 Bean 自动受益


















