CDI (Part 1): Factory With @Produces


CDI(第1部分):具有@Produces的工厂 在本系列的第一部分中,让我们探索CDI 2.0,它如何与您的代码交互(在此示例中为记录器)以及如何使用@Produces批注。 Alexandre Gama用户头像 经过 亚历山大·加玛(Alexandre Gama) · 可能。29,20 · Java专区 · 教程 喜欢 (23) 评论 (11) 救 鸣叫 43.48千 次浏览 你好!

这是第1部分中的CDI系列在Java中,包含:

第1部分:具有@Produces批注的CDI中的工厂 第2部分:CDI资格赛 第3部分:CDI中的事件和观察者 第4部分:CDI和延迟初始化 第5部分:CDI中的拦截器 第6部分:CDI依赖注入和替代方法 第7部分:与CDI装饰器一起使用 在本文中,我们将看到如何使用@Produces注释,它可能是Java CDI世界中最常用的注释之一!

让我们在这里将我们的挑战情境化!我们必须在程序中创建以下步骤:

  • 创建Checkout类以...您知道...完成结帐
  • 在控制台中记录操作
  • 创建一个Logger类,以将该日志保留在自己的类中,保持内聚性
  • 自定义此日志记录器以接收指示应使用哪种日志模式的配置

很简单,对不对?让我们跳入代码!

步骤1:在CDI 2.0中创建特殊的主类 在创建执行CDI代码的主类之前,让我们创建重要的Checkout类:

public class Checkout {

    public void finishCheckout() {
        System.out.println("Finishing Checkout");
    }

}

伟大的!

在此示例中,我们将使用CDI 2.0,它允许我们以独立方式使用CDI !

要创建将为我们带来CDI功能的CDI容器,只需创建以下代码:

CDI<Object> container = new Weld().initialize()

好的!让我们看一下具有Checkout类实例的完整代码:

public class MainApplication {

    public static void main(String[] args) {
        try (CDI<Object> container = new Weld().initialize()) {
            Checkout checkout = container.select(Checkout.class).get();

            checkout.finishCheckout();
        }
    }
}

很简单,不是吗?请注意以下代码:

Checkout checkout = container.select(Checkout.class).get();

该代码与以下代码相同:

@Inject 
private Checkout checkout;

现在,该执行我们的CDI示例了,看看环境还可以!

您将在控制台中看到以下内容:

INFO: WELD-ENV-002003: 
Weld SE container STATIC_INSTANCE initialized Finishing Checkout

伟大的!一切都准备就绪并开始运行!

步骤2:为记录器创建专门的类 我们的代码应该具有良好的内聚性,因此我们应该创建一个负责记录某些消息的类。此类将称为SpecialLogger,如下所示:

public class SpecialLogger {

    public void log(String message) {
        System.out.println("LOG: " + message);
    }

}

完美的!现在,我们想更新Checkout类以使用Logger类:

public class Checkout {

    private SpecialLogger logger;

    public void finishCheckout() {
        logger.log("Finishing Checkout");
    }

}

听起来不错,因为现在Checkout类不知道Log的工作原理,我们只是在使用它!

步骤3:配置模式以记录消息 有时我们想更改日志打印输出的模式。这些模式可以是:

  • 调试模式
  • 信息模式
  • 错误模式
  • 等等。

我们的SpecialLogger应该会收到所需的日志,并使用此配置模式打印出消息。

是时候创建将接受Log模式的Configuration类了:

public class LogConfiguration {

    private boolean infoMode;

    private boolean debugMode;

    public LogConfiguration(boolean infoMode, boolean debugMode) {
        this.infoMode = infoMode;
        this.debugMode = debugMode;
    }

    public boolean isInInfoMode() {
        return infoMode;
    }

    public boolean isInDebugMode() {
        return debugMode;
    }

}

我知道,这可能会更好,但这只是为了使示例保持简洁。

让我们更改SpecialLogger类,使其能够基于配置模式记录消息:

public class SpecialLogger {

    @Inject
    private LogConfiguration configuration;

    public SpecialLogger(LogConfiguration configuration) {
        this.configuration = configuration;
    }

    public void log(String message) {
        if (configuration.isInDebugMode()) {
            System.out.println("DEBUG LOG: " + message);
        }
        else if (configuration.isInInfoMode()) {
            System.out.println("DEBUG LOG: " + message);
        } else {
            System.out.println("DEFAULT LOG: " + message);
        }
    }

}

如您所见,我们正在检查日志是否应使用“调试”或“信息”模式,否则必须使用“默认”模式将消息打印出来。

让我们尝试运行它:

WELD-001408: 
Unsatisfied dependencies for type SpecialLogger with qualifiers @Default
 at injection point [BackedAnnotatedField] 
 @Inject 
 private com.hackingcode.cdi.produces.Checkout.logger

是的,我们将面临一个例外。这是有道理的。CDI不知道如何注入SpecialLogger对象。

CDI将尝试以下步骤:

嘿,我可以看到您需要一个SpecialLogger对象。没关系对我来说。我会尝试找到这堂课 我发现了SpecialLogger类 我现在尝试为您创建一个新的SpecialLogger对象 哦,我做不到!该SpecialLogger接收在其构造LogConfiguration。我不知道它是什么,也不知道如何创建它! 让我们教CDI下一步如何使用LogConfiguration类!

步骤4:在CDI中使用@ProducesAnnotation 是时候创建一个工厂以基于LogConfiguration创建SpecialLogger了:

public class SpecialLoggerFactory {

    public SpecialLogger createLogger() {
        LogConfiguration logInDebugMode = new LogConfiguration(true, false);

        return new SpecialLogger(logInDebugMode);
    }

}

这是一个非常简单的Factory类。它具有方法createLogger(),该方法返回LogConfiguration对象。

但是CDI还不知道此类,甚至它的方法!让我们使用批注@Produces。

public class SpecialLoggerFactory {

    @Produces
    public SpecialLogger createLogger() {
        LogConfiguration logInDebugMode = new LogConfiguration(true, false);

        return new SpecialLogger(logInDebugMode);
    }

}

@Produces向CDI指示在需要LogConfiguration对象时应使用方法createLogger()

@Produces注释会说CDI: 嘿,CDI,当您需要在某个地方注入SpecialLogger对象时,请使用createLogger()方法

当然,方法createLogger()的返回对象必须与您感兴趣的类型相同,在本例中为SpecialLogger。

我真的希望这篇文章对您有所帮助!


原文链接:http://codingdict.com