【问题标题】:Performance: Utility class vs. CDI bean性能:实用程序类与 CDI bean
【发布时间】:2015-03-02 16:04:17
【问题描述】:

我想将常用的应用程序逻辑外部化为一个名为Helper的“实用程序类”。应用程序逻辑需要其他 CDI bean 才能工作。

两种可能:

一)

@SessionScoped
class ControllerWithCdiBean {

  @Inject
  Helper helper;

  public void doIt() {
      Object result = helpder.calculate();
  }
}

@RequestScoped
class Helper{

  @Inject
  Service anyService;

  public Object calculate() {
     return anyService.calc();
  }
}

b)

@SessionScoped
class ControllerWithStaticCallsViaDeltaspike {

  public void doIt() {
      Object result = Helpder.calculate();
  }
}

class Helper{

  private static Service anyService = BeanProvider.getContextualReference(Service.class);

  public static Object calculate() {
     return anyService.calc();
  }

性能怎么样?有什么显着的区别吗?两种解决方案对我来说都是可能的,一种解决方案比另一种更好吗?

一个缺点: 每个请求都会初始化 Helpder。

【问题讨论】:

  • 我会选择 a。实用程序类是邪恶的
  • @SvetlinZarev 你的意思是像java.util.Arraysjava.util.Collections 这样的类和整个Apache Commons Xyz 库都是邪恶的?你肯定从来没有用过它们:)
  • @LuiggiMendoza 有区别。 ArraysCollections 随 JRE 一起提供,而 Helper 没有。此外,过度使用静态方法(因此是实用程序类)会导致程序代码并使其难以测试。过度使用实用程序类违反 OOP 和 TDD 的原则,应尽可能避免,在 OP 的情况下,绝对可以不使用实用程序类。
  • @SvetlinZarev 很好的理论,但遗憾的是并不适用于所有现实世界的应用程序。在某些用例中,您的方法将在多个类中使用并执行相同的操作,因此最好将这些方法打包到一个类(或一组类)中,该类(或类组)不需要特定实例来使方法工作例如验证 String 是否为空或 null。有些人意识到这一点并在他们的库中使用它们:Apache Commons 系列:Lang、IO 等。Guava、cglib 等等。

标签: java performance cdi weld


【解决方案1】:

将您的Helper 课程标记为@ApplicationScoped。这样,您将在每个应用程序上下文中拥有一个实例。

不过,如果它只是一个实用程序类,它根本不应该是一个托管 bean。我会将其标记为final,定义一个private 构造函数并将所有方法标记为static。这是因为它是一个实用程序类,它不需要维护任何状态。

【讨论】:

  • “私有静态服务 anyService”是否会出现问题,因为我只向 CDI bean 注入了一次引用 (=proxy) 并在 Helper 的整个生命周期内让它在那里?
  • 那么你没有实用程序类,而是一个代理类。如果这是您的目的,请使用方法 A 并将您的代理标记为 @ApplicationScoped
  • Apache Commons Xyz 课程绝对有帮助...但毕竟,我认为,我的 Helper 远不止这些。它包含“更多”逻辑,在 all 情况下不可重用。因此,我宁愿采用方法 a) 并将其设为 @ApplicationScoped。这对组件测试有好处,尽管有像 Powermock 这样的框架可以轻松测试静态方法。
猜你喜欢
  • 2023-03-10
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
  • 2012-11-21
相关资源
最近更新 更多