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世界中最常用的注释之一!
让我们在这里将我们的挑战情境化!我们必须在程序中创建以下步骤:
很简单,对不对?让我们跳入代码!
步骤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()方法
@Produces
当然,方法createLogger()的返回对象必须与您感兴趣的类型相同,在本例中为SpecialLogger。
我真的希望这篇文章对您有所帮助!
原文链接:http://codingdict.com