【问题标题】:Accessing CDI from simple objects?从简单对象访问 CDI?
【发布时间】:2021-09-13 16:39:45
【问题描述】:

假设我有一个配置类可通过股票 CDI 访问,它定义了一些应用程序范围的参数:

@ApplicationScoped
class AppConfig {
  public double getMaxAllowedBrightness() { ... }
};

我的数据对象有一个简单的类:

class LightSource {
  double brightness;
  ...

  boolean isValid() {
    double maxAllowedBrightness = ...; // Somehow use AppConfig#getMaxAllowedBrightness() here
    return brightness <= maxAllowedBrightness;
  }
}

我的数据对象如何访问单个 AppConfig 实例?

不知何故,我讨厌将 AppConfig 自动装配到每个数据对象中的想法(它们有很多)。有没有其他方法可以从我的数据对象访问上述示例中的 AppConfig? 在这里使用的最佳模式是什么?

【问题讨论】:

  • 能否请您说明您所针对的 CDI 规范的版本?
  • 最好是 1.0(J2EE 6 引入的东西)。但是什么都可以。

标签: java cdi


【解决方案1】:

最简单的例子是运行时查找,类似于:

import jakarta.enterprise.inject.spi.CDI;
CDI.current().select(cls).get();

cls 是您要查找的类。 (注意包名,这是最新版的CDI 2.x在新的jakarta命名空间,原来在javax。)

从那里开始更详细,但这就是它的要点。

请注意,从语义上讲,自动装配某些东西和执行运行时查找之间几乎没有区别,尤其是对于在实例级别大部分是静态的东西。它仍然是一个依赖项。您仍然必须触摸类的代码才能完成它。

依赖自动装配的一个好处是您可以根据情况禁用它,并且该类恢复为一个简单的 bean,您可以随心所欲地进行操作。在查找中编码,还不止这些。

动态查找更多用于特殊情况。

【讨论】:

    【解决方案2】:

    在我当前的项目中,我们的团队一直在使用 @Value 注释来执行此操作。在我们的例子中,我们在一个属性 bean 中拥有所有属性,我将其称为 mainAppConfiguration。 bean 由 main-app-config.properties 之类的属性文件填充(使用 Properties prop = new Properties().load(mainAppConfigFilePath) 方法读入 bean。

    假设您设置了类似的东西,那么我们使用一点 SpEL 魔法将属性注入到需要它们的类中:

      private Integer refreshRateSeconds;
      
      @Value("#{ mainAppConfiguration.getProperties()['funny-property-base-name.refreshRateSeconds'] }")
      public void setRefreshRateSeconds(Integer refreshRateSeconds) {
        if (refreshRateSeconds == null) {
          throw new IllegalArgumentException("Required config property 'funny-property-base-name.refreshRateSeconds' was not found"));
        }
        this.refreshRateSeconds = refreshRateSeconds;
      }
    

    Baeldung 有示例(没有默认值)和more with defaults

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-31
      • 1970-01-01
      • 2015-01-04
      相关资源
      最近更新 更多