Bearcat Bean作用域实战指南:singleton、prototype、lazy-init、request 4种作用域怎么选

📅 2026/8/22 12:31:55
Bearcat Bean作用域实战指南:singleton、prototype、lazy-init、request 4种作用域怎么选
Bearcat Bean作用域实战指南singleton、prototype、lazy-init、request 4种作用域怎么选【免费下载链接】bearcatpowered by enhanced javaScript objects项目地址: https://gitcode.com/gh_mirrors/be/bearcatBearcat 是一个面向 JavaScript 对象的轻量级依赖注入DI与面向切面AOP框架它让普通 JS 对象POJO通过自描述元数据即可完成组装。本文是 Bearcat Bean 作用域实战指南带你快速搞懂 singleton、prototype、lazy-init 和 request 这 4 种作用域的差异与选择方法帮新手少踩坑、写出更稳的 IoC 容器代码。一张表看懂 4 种作用域作用域元数据写法实例数量创建时机典型场景singleton默认可不写全容器 1 个容器启动时预创建服务、仓储、配置类prototypethis.$scope prototype每次获取 1 个每次getBean时有状态对象、临时任务lazy-initthis.$lazy true通常是 1 个首次被使用时初始化慢、很少用的 Beanrequest用prototype模拟每请求 1 个每个请求处理时Web 会话数据、请求上下文 Bearcat 原生支持前三种singleton、prototype、lazy标记request是一种基于prototype的编程惯例后文会说明。Bearcat 是如何识别作用域的Bearcat 的核心思想是自描述的 JavaScript 对象框架扫描目录由context.json中的scan指定中的 JS 文件读取构造函数里的$开头的元数据属性比如$id、$scope、$lazy。作用域常量定义在 lib/util/constant.js默认作用域就是singleton。元数据解析后生成 BeanDefinition见 lib/beans/support/beanDefinition.js其中scope与lazyInit两个字段决定了后续行为。真正的分流发生在 lib/beans/beanFactory.jssingleton 走单例缓存prototype 则每次直接createBean新建实例。singleton默认的共享实例最简 Bean 只需要一个$id作用域自动为 singleton// 参考示例 examples/simple/app/car.js var Car function() { this.$id car; }var car1 applicationContext.getBean(car); var car2 applicationContext.getBean(car); // car1 car2永远是同一个实例singleton Bean 在容器启动时就被 preInstantiateSingletons 按$order顺序预创建并缓存进 SingletonBeanFactory。适合无状态的服务、工厂、DAO 这类全局共享组件。注意不要在 singleton 实例属性里存用户级/请求级可变状态否则多线程Node.js 事件循环内的异步回调交错时会互相污染。prototype每次都是新实例// 参考示例 examples/simple_prototype/app/car.js var Car function() { this.$id car; this.$scope prototype; }每次getBean(car)都会执行构造函数产生互不相干的独立实例beanFactory.js。prototype Bean 不会在启动时预创建也不参与单例缓存。适合需要独立生命周期的有状态对象比如一次性的任务执行器、表单处理器。lazy-init把初始化推迟到用时在 singleton 基础上加一行$lazy true// 参考示例 examples/simple_lazy_init/app/car.js var Car function() { this.$id car; this.$lazy true; }启动阶段BeanUtils.sortBeanDefinitions 会把lazyInit的 Bean 排除在预创建列表之外首次通过 getBeanProxy 拿到的是一个动态代理真正的方法调用发生时才触发目标 Bean 的创建与初始化代理实现见 lib/aop/framework/dynamicMetaProxy.js。适合初始化成本高加载大模型、建立昂贵连接但使用频率低的 Bean能显著缩短应用启动时间。⚠️ 易错点lazy只影响什么时候创建不改变作用域——它本质上仍是 singleton创建后照样全局共享。别指望 lazy 带来隔离。request在 Node.js 中实现请求级隔离Bearcat 没有内置request作用域关键字代码库中的 request 相关实现是 lib/util/requestUtil.js 的浏览器脚本加载工具与此无关。推荐做法是用 prototype 作用域 在请求处理函数里getBean。// 请求处理器内 router.get(/order, function(req, res) { var orderBuilder applicationContext.getBean(orderBuilder); // 每请求独享 // ...处理业务处理完即弃 });这样每个 HTTP 请求拿到独立的 Bean 实例天然避免并发请求之间的状态串扰。配合 ApplicationContext 的getBean即可无需任何额外配置。怎么选3 步决策法 会被多人/多处共享且无状态→singleton不写$scope即可省心。实例上会挂可变状态→prototype如果状态只属于一次 HTTP 请求那就是request 模式prototype 请求内获取。初始化很慢、冷启动不想等它→ 在 singleton 上追加$lazy true。另外两个隐藏规则要记牢Model 类 Bean 会被强制为 prototypebeanFactory.js因为数据模型天然是每次一份singleton 的销毁由容器统一管理destroySingletons会遍历缓存并调用$destroy指定的方法beanFactory.jsprototype 实例的清理则需要你自己负责。核心源码路径速查内容路径作用域常量定义lib/util/constant.jsBean 创建分流逻辑lib/beans/beanFactory.js单例缓存实现lib/beans/singletonBeanFactory.js启动预创建跳过 lazylib/util/beanUtil.jsprototype 示例examples/simple_prototype/app/car.jslazy-init 示例examples/simple_lazy_init/app/car.js上下文入口lib/context/applicationContext.js掌握这 4 种作用域的取舍你就抓住了 Bearcat 依赖注入中最实用的部分共享交给 singleton隔离交给 prototype慢启动交给 lazy请求级状态交给prototype 请求内获取。照着上面的决策法选型绝大多数业务场景都不会出错。【免费下载链接】bearcatpowered by enhanced javaScript objects项目地址: https://gitcode.com/gh_mirrors/be/bearcat创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考