【发布时间】:2021-10-18 19:59:47
【问题描述】:
首先,我想向您展示我的图表: Diagram。怎么看,我们有两个模块“Ticket”和“Notification”。通知模块依赖于工单模块。一旦“TicketService”创建了一个工单,就会调用来自 EmailHandler 组件的 sendEmail 方法。不幸的是,我不知道如何解决这个问题。
【问题讨论】:
标签: java spring dependencies
首先,我想向您展示我的图表: Diagram。怎么看,我们有两个模块“Ticket”和“Notification”。通知模块依赖于工单模块。一旦“TicketService”创建了一个工单,就会调用来自 EmailHandler 组件的 sendEmail 方法。不幸的是,我不知道如何解决这个问题。
【问题讨论】:
标签: java spring dependencies
存在适用于任何架构的模式。当您的TicketService 创建票证时,它会生成一个事件,任何感兴趣的进程都会订阅。
在 EJB 中,它可以使用 @Observes annotation 来解决,但也可以使用任何事件代理(流... kafka、activemq、spark...)。
Spring Boot 不支持直接事件注册(如@Observes 为described here),但您可以使用它或任何其他事件代理。
如果您不使用 Java 企业服务,我建议您根据项目的需要使用代理(例如,kafka 如果它很大,或者nats 为简单起见)。
要显示使用 NATS 的最小代码示例,您可以使用以下方式连接到 NATS 服务器代理:
final Connection nc = Nats.connect("nats://localhost:4222");
那么,任何有兴趣知道已创建新票证的进程都会监听此类事件
final Subscription sub = c.subscribe(CHANNEL);
while (true)
sendMessageForTicket(sub.nextMessage(Duration.ofDays(365)).getData());
TicketService 将发送一条消息以供所有这些侦听进程接收
c.publish(CHANNEL, myCreatedTicketData);
当然,所有进程都是解耦的,可横向扩展的(例如微服务),并且只共享某个Ticket存在的知识。
【讨论】:
spring标记了这个问题,只是为了澄清。
您的图表解释了架构(组件和关系),而忽略了纯 java 中的技术细节(技术/框架)。如果你愿意,你可以在纯 java 中快速实现它。
为 'ticket' 和 'notification' 模块创建两个 java 包。
为 EmailHandlerInterface 创建一个 java 接口,并将其放入 'ticket' 包中。
在'notification'包中,创建EmailHandler类并实现创建的EmailHandlerInterface
在'ticket'包中,将Ticket对象实现为简单的java POJO类,
在 'ticket' 模块中,创建 TicketSercice 类,该类将 Ticket 对象作为原型并返回创建的 Ticket 对象。
您需要在 "ticket package" 中添加一个额外的对象(我们将其命名为 TicketModuleExecutor 之类的)。您必须通过 EmailHandleInterface 向它注入一个 EmailHandler。这个对象应该有一个方法'execute',它创建一个Ticket对象,将它传递给TicketService,并在TicketService::create通过接口调用EmailHandler::sendEmail成功后执行。
在“默认”包中,使用 main 方法创建主应用程序类(这样您就可以执行您的程序)。在 main 内部,你初始化你的 'ticket' 模块主类,初始化一个 EmailHandler 对象并将它传递给 main,然后调用 TicketModuleExecutor.execute() 来完成整个程序。
一般来说,如果您在实施过程中遵循 SOLID 和 IoC 等所有良好实践,您以后可以轻松地将代码迁移到任何框架,而无需更改架构。
我可能犯了一些小错误;因为不使用英语进行编码就很难编码,这不是您的母语:-D 但我不会为您编写代码,因为我不想为您解决您的任务。您应该自己实现该应用程序。
【讨论】:
在 Spring 中,您首先应该定义适合您的模块。如果是单独的独立应用程序,则选择通信方式1.同步或2.异步。对于同步选项,您可以使用 rest 或 servlet。 2. 对于异步,您可以使用 KAFKA、RabitMQ、JMS 或任何其他代理。 如果你想在一个应用程序中包含模块,你可以使用我的普通 java 示例并使用 Spring Beans 来实现它,或者你可以使用 spring 事件或 AOP 方法。该图的实现方式有多种选择;-)
无论如何,对于这样一个简单的情况,我建议 KISS(保持简单愚蠢)使用 Spring bean 对象实现应用程序在这里就足够了。
【讨论】: