依赖注入带来的性能问题

2024-01-16

在我的探查器报告中,我越来越多地看到使用依赖项注入进行基于模拟的测试的结果。许多依赖项是静态的,但因为我们想要单独测试方法,所以它们被更改为实例成员,如下例所示:

class ShortLivedThing {
   IDependency1 dep1;
   IDependency1 dep2;
   IDependency1 dep3;
   ...

   int TheRealData;

   // Constructor used in production 
   public ShortLivedThing() {
     dep1 = new Dep1(); dep2 = new Dep2(); dep3 = new Dep3();
   }

   // DI for testing 
   public ShortLivedThing(IDependency1 d1, IDependency2 d2, IDependency3 d3) { 
     dep1 = d1(); dep2 = d2(); dep3 = d3();
   }
}

反过来,大多数时候,依赖关系还有其他依赖关系,依此类推。这导致实例化一棵(大部分是“静态”)对象树每次方法调用是在测试之外完成的。每个对象都非常小(只有几个指针),但树效应将其转化为不断增加的性能损失。

我们对于它可以做些什么呢?


在我看来,您需要利用适当的依赖注入框架可以提供的功能。不要使用不同的构造逻辑进行测试/生产。

使用 Spring,单例注入仅在容器启动时执行。每次都会进行原型注射。每次运行单元测试时也会完成完整的接线(如果已接线)。因此分析单元测试通常不是一个好主意。

也许您使用的单例作用域太少而原型作用域太多? (原型=每次都有新实例)

spring 注入的好处是您可以使用作用域代理,这意味着您的对象图可以如下所示:

 A Singleton
 |
 B Singleton
 |
 C Prototype (per-invocation)
 |
 D Singleton
 |
 E Session scope (web app)
 |
 F Singleton

每个请求在每个会话中只会创建 1 个 C 实例和 1 个 E 实例。 A、B、D 和 F 是单例。如果它不是 Web 应用程序,则默认情况下没有会话作用域,但您也可以创建自定义作用域(“窗口”作用域对于窗口桌面应用程序来说听起来很酷)。这里的线索是,您可以在任何级别“引入”作用域,实际上您可以拥有十层单例对象,并且突然出现一些会话作用域的内容。 (这确实可以彻底改变您在分层架构中实现一些横切功能的方式,但这是一个不同的故事)

我认为,这确实在 DI 模型中提供了尽可能少的对象创建。

虽然这是 Spring for Java,但我相信许多其他 DI 框架应该支持类似的功能。也许不是最简约的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

依赖注入带来的性能问题 的相关文章

  • 在同一项目中同时使用 AddDbContextFactory() 和 AddDbContext() 扩展方法

    我正在尝试使用新的DbContextFactory中讨论的模式EF Core 文档的 DbContext 配置部分 https learn microsoft com en us ef core dbcontext configuratio
  • 没有使用 Angular 2 和 Http 服务的 XHRBackend 提供程序

    我正在构建一个基于 angular2 生成 angularcli webpack scss 和面向模块的项目 对于 http 请求 我决定创建一个由身份验证服务使用的服务 全部在 CoreModule 中引用 import NgModule
  • 使用 Reader Monad 进行依赖注入

    我最近看到了谈话极其简单的依赖注入 http www youtube com watch v ZasXwtTRkio and 无需体操的依赖注入 http vimeo com 44502327关于 Monads 的 DI 并留下了深刻的印象
  • Guice 忽略注入构造函数参数上的 @Nullable

    我正在使用 Guice v 3 0 并且有一个值被注入到构造函数中 该值可以为 null 因此我在构造函数中使用 Nullable 来自 javax annotations 注释了该参数 public MyClass Parameter1
  • Angular 2 Renderer2 - 它是如何工作的

    我试图理解在 Angular 2 的指令或组件中添加 renderer2 装饰的必要性 来自文档 渲染器2文档 https angular io api core Renderer2他们没有提供其工作原理的示例 谁能用完整的例子解释一下 请
  • 无法构造 String 类型

    我正在使用 Web api 和 Unity 并且在尝试打开默认 帮助 区域时收到以下错误 InvalidOperationException The type String cannot be constructed You must co
  • 是否有适合 Java 1.4 和 SE (Swing) 应用程序的优秀 DI 框架?

    我正在寻找一个适用于在 JDK 1 4 下运行的 Java SE Swing 应用程序的依赖注入框架 有没有我可以使用的推荐 DI 框架 Guice 和其他基于注释的框架已经退出 我不想搞乱像 Retroweaver 这样的东西 另外 Sp
  • Dagger @Reusable 范围与 @Singleton

    来自用户手册 http google github io dagger users guide html 有时你想限制 Inject 构造的次数 类已实例化或调用了 Provides 方法 但您没有 需要保证在期间使用完全相同的实例 任何特
  • 如何在 servlet 线程中获取新的有状态会话 bean?

    我正在尝试 EJB3 我想将一个有状态会话 bean 注入到 servlet 中 以便每个访问该 servlet 的用户都会获得一个新的 bean 显然 我不能让 bean 成为 servlet 的实例变量 因为它将被共享 显然不允许注入局
  • Laravel 5 包中依赖注入的最佳方法

    我正在为 Laravel 5 开发一个包 现在我需要受益于依赖注入来拥有一个更具可扩展性和可靠性的应用程序 我不知道最好采用哪种方法以及为什么 这是我的一段代码 我需要注射Lang类依赖 class MyController extends
  • Java EE7 中 Qualifier 中的 @Nonbinding 注释的目的是什么?

    我正在阅读CDIJavaEE 7 中的注入特别是使用 Qualifier and Produces注入一个custom Data type变成一颗豆子 我有以下代码取自JBoss 文档 http docs jboss org weld re
  • 如何在 Caliburn.Micro 中使用 Conductor 的依赖注入

    我有时用Caliburn Micro http caliburnmicro com创建应用程序 使用最简单的 BootStrapper 我可以像这样使用 IoC 容器 SimpleContainer private SimpleContai
  • Guice 字段注入不起作用(返回 null)

    我在使用 Guice 时遇到空值问题 接下来我将向您展示一个类似场景的示例 我知道字段注入是一种不好的做法 但我希望它在演示中像这样工作 我有一个名为B 这是我要注入的 class B Inject public B public void
  • 从 EntityManagerFactory 连接 EntityManager 的问题

    我知道 spring 有它自己的 JPA 对象工厂 但我想让它按原样工作 从那里我将研究最佳实践 我只是处于理解过程中 这是我尝试为其生成 bean 的实际代码 EntityManagerFactory emf Persistence cr
  • 从另一个命令 Handle() 方法中调用命令

    嗨 我正在使用简易注射器 https simpleinjector orgDI 库并一直在关注一些关于围绕命令模式设计的架构模型的非常有趣的材料 同时 在我的架构的命令方面 https cuttingedge it blogs steven
  • 用dagger 2查看依赖注入

    我有一个自定义视图扩展TextView 我应该在哪里调用我的组件来注入视图 component inject customTextView 因此 我发现我需要在自定义视图的构造函数中添加注入 在所有视图中 或者使一个调用另一个 Exampl
  • 有状态对象的 IoC 依赖注入(非全局)

    我是这个 IoC 和 DI 业务的新手 我觉得如果你传递的是全局范围的对象 我就明白了这个概念 但是当你需要传递一个全局范围的对象时 我不明白它是如何工作的特定的逻辑状态 因此 例如 如果我想将一个人对象注入到一个写入文件命令对象中 我如何
  • MVC 3 将实体作为接口传递

    我目前正在开发一个 MVC 3 项目 使用 Ninject 作为我的 DI 业务对象存储在单独的程序集中 我遇到了控制器参数的问题 当回发 CRUD 操作时 我收到错误 无法创建接口实例 我知道您无法创建接口的实例 但似乎解决此问题的唯一方
  • @DependsOn 注释的逆

    Spring 可能还有其他 DI 容器 但我使用的是 Spring 识别 DependsOn 注释 您可以使用它来标识必须在该 bean 之前启动的任何其他 bean 例如 Component DependsOn initiatedFirs
  • 静态方法中的统一

    一个可能很简单的问题 但很奇怪为什么我不知道该怎么做 Unity PRISM 和静态方法 在这种特殊情况下 需要使用扩展方法 但一般来说 如何在静态方法中访问 统一提供的实例 想想例如我想访问一个日志服务来记录我在静态方法中所做的一些事情

随机推荐

  • 替换 javascript 中的 JSON 键

    假设我有一个 JSON 对象 例如 var myjson com mycompany top Element com mycompany top count 10 com mycompany top size 0 我想用冒号替换键中的点 句
  • F3 更改 css 文件的相对 URi

    我是一个尝试 F3 的新手 我的示例应用程序基本上可以工作 但是对 css 文件的引用发生了更改并导致找不到 它看起来像 htaccess 问题 但我似乎无法修复它 我的 css 文件指定为 我的 htaccess 文件看起来像 Rewri
  • 为什么 UITextView 在调整大小后会在错误的框架中绘制文本?

    我陷入了某种魔力 当我尝试更改 UITextView 框架 在本例中使用 UISlider 时 文本会在比框架更小的其他区域中绘制 多次调整大小 有趣的是 如果我们在尝试使框架变大时滑动得足够快 文本就会绘制在非常正确的区域中 有人可以解释
  • 动态大小类型总是在堆上吗?

    我对 Rust 的学习让我了解了动态大小类型 DST 并且我知道这些类型的大小在编译时无法得知 例如 str 我现在的问题是 我说 DST 永远不能存在于堆栈上 它们只存在于堆上 这样说对吗 另外 另一方面 说大小类型可以存在于堆栈中是否正
  • GridView 排序仅有效一次

    我有一个网格 它仅按升序排序一次 然后什么也没有发生 aspx文件代码
  • 如何在 Swift 4 中创建一定大小的数组?

    如何制作一个包含 1000 个浮点数的简单数组 我已经尝试过这个 var computeArray Array
  • 如何从node.js缓冲区获取int

    是代码 var time new Buffer 506BF1E3 hex time toString Pk 0x506BF1E3 1349251555 UNIX时间 如何获取 1349251555 表格time缓冲 这个也能达到目的 通过使
  • SQL Server:过滤 sp_who2 的输出

    在SQL Server下 有没有一种简单的方法来过滤sp who2的输出 例如 假设我只想显示某个数据库的行 你可以尝试类似的东西 DECLARE Table TABLE SPID INT Status VARCHAR MAX LOGIN
  • 如何检查使用哪个编译器来构建Python

    有没有办法知道使用哪个编译器来构建Python安装在特定的linux机器上 我尝试使用ldd on the Python动态库 1 但我无法理解它是否是用gcc或英特尔编译器 1 ldd libpython2 7 so 1 0 linux
  • Clang 在 c++98 模式下使用 std::stoi 编译代码

    我需要用 C 98 编译我的 cpp 而不是我的学校项目的 C 11 所以我用了 std c 98编译 CPPFLAGS Wall Werror Wextra std c 98 但我犯了一个错误并使用了C 11std stoi功能 i st
  • 如何让浮动div居中?

    我想将下面模型中出现的三个 div 居中 全部都有 float left 这可能吗 我不介意有包装器div Text align center 和 display inline block 不适用于我的代码 如果你想让它们居中 你就不能浮动
  • 发布时母版页出现“无法加载类型”错误

    本地查找一切正常 但是当我将 ASP NET 应用程序发布到远程服务器时 出现以下错误 Server Error in Application Parser Error Description An error occurred durin
  • 页面加载时的 JSF 重定向

    简短的问题 是否可以进行重定向 例如当用户未登录时 当呈现页面时 为此你should http java sun com products servlet Filters html use a Filter http java sun co
  • 如何用颜色突出显示浏览器选项卡

    我有一个聊天 Web 应用程序 我需要一项功能 其中如果特定用户在浏览器窗口中打开了多个选项卡 并且聊天选项卡不是活动选项卡 那么如果他从另一端收到 ping 则聊天选项卡应该自动突出显示以吸引用户注意力 我打算用 jQuery 来做这件事
  • 高调的 MonoTouch 应用程序? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想要一些使用 MonoTouch 创建的高调应用程序的示例 您打电话回家的应用程序 进入所属类别前 25 名的应用程序 我在哪里可以找到此类应用程序
  • 如何在 Debian postinst 脚本中获取新安装的版本?

    Per the Debian 政策手册 http www debian org doc debian policy ch maintainerscripts html 我的 postinst 脚本在升级和配置时被调用 如 postinst
  • Hibernate Validator - 添加动态 ConstraintValidator

    了解后Hibernate 自定义验证器 https docs jboss org hibernate validator 4 0 1 reference en html validator customconstraints html 它让
  • 无法使用 GAE/J DataNucleus 插件版本 2.1.2 获取新创建的 JDO 持久实体的 ID

    我的问题 我正在使用新的 1 7 5 GAE J SDK 将我的应用程序从 GAE J 的 DataNucleus 插件版本 1 x 移植到 2 0 这将我的 JDO 版本从 2 3 更改为 3 0 1 我的持久实体类有一个编码字符串类型的
  • Javascript - 将 INI 文件解析为嵌套关联数组

    我是 Javascript 新手 在将 INI 格式的文件解析为嵌套对象时遇到问题 我的文件格式如下 ford car focus transmission standard ford car focus engine four cylin
  • 依赖注入带来的性能问题

    在我的探查器报告中 我越来越多地看到使用依赖项注入进行基于模拟的测试的结果 许多依赖项是静态的 但因为我们想要单独测试方法 所以它们被更改为实例成员 如下例所示 class ShortLivedThing IDependency1 dep1