服务中从零实现应用服务的领域实体及消息处理

举报
码乐 发表于 2025/02/25 10:42:43 2025/02/25
3.5k+ 0 0
【摘要】 1 简介JAVAEE中有3个类型的Bean,本文例子中的组件实现了EJB中Bean的这三种类型功能: Session Bean, Entity Bean, Message-Driven Bean.比如Session Bean的职责:维护一个短暂会话,当客户端执行完成后,Session Bean和它的数据会消失。Entitv Bean的职责:维护一行持久稳固的数据...

1 简介

JAVAEE中有3个类型的Bean,本文例子中的组件实现了EJB中Bean的这三种类型功能:

    	Session Bean,
      Entity Bean,
      Message-Driven Bean.

比如Session Bean的职责:维护一个短暂会话,当客户端执行完成后,Session Bean和它的数据会消失。

Entitv Bean的职责:维护一行持久稳固的数据,如果客户端终止或者服务结束,底层的服务会负责entity Bean数据的存储。

Message-Driven Bean的职责:结合了Session Bean 和JMS,允许异步接收消息。

2 实现Bean的功能替代

在web框架的费用管理系统中,可以通过不同组件和职责实现 EJB 的三种 Bean(Session Bean、Entity Bean、Message-Driven Bean)的功能。以下是对 EJB 三种类型在示例中对应实现的映射和说明:

2.1. Session Bean 对应

职责:
维护短暂会话。

生命周期与客户端请求相关,完成后即销毁。

对应的组件:
在费用管理系统中,Session Bean 的职责可以由应用层服务 (ExpenseAppService) 来模拟。它的逻辑在每次请求时
被实例化,用于处理请求相关的业务逻辑,并在请求结束后销毁,不保存持久状态。

示例:

	type ExpenseAppService struct {
	    expenseRepo domain.ExpenseRepository
	}

	func NewExpenseAppService(repo domain.ExpenseRepository) *ExpenseAppService {
	    return &ExpenseAppService{expenseRepo: repo}
	}

	func (s *ExpenseAppService) CreateExpense(req CreateExpenseRequest) error {
	    expense := domain.NewExpense(req.UserID, req.Amount, req.Category, req.Remark)
	    return s.expenseRepo.Save(expense)
	}

作用:每个 HTTP 请求都会创建一个 ExpenseAppService 实例,用于处理当前的会话任务,完成后释放。
短暂性:ExpenseAppService 的实例仅在请求期间有效。

2.2. Entity Bean 对应

职责:

负责与数据库中的持久数据交互。
实现数据的创建、读取、更新和删除(CRUD)。
生命周期独立于客户端请求。

对应的组件:

在费用管理系统中,Entity Bean 的职责可以由领域层的实体类 (Expense) 和基础设施层的存储库 (InMemoryExpenseRepository) 来实现。

示例:

实体类(Entity Bean 功能核心):

	type Expense struct {
	    ID        string
	    UserID    string
	    Amount    float64
	    Category  string
	    Remark    string
	    CreatedAt time.Time
	}

	func NewExpense(userID string, amount float64, category, remark string) *Expense {
	    return &Expense{
	        ID:        generateID(), // 自定义 ID 生成逻辑
	        UserID:    userID,
	        Amount:    amount,
	        Category:  category,
	        Remark:    remark,
	        CreatedAt: time.Now(),
	    }
	}

基础设施层的存储库(Entity Bean 的持久化支持):

	type InMemoryExpenseRepository struct {
	    data map[string][]*domain.Expense
	}

	func (r *InMemoryExpenseRepository) Save(expense *domain.Expense) error {
	    r.data[expense.UserID] = append(r.data[expense.UserID], expense)
	    return nil
	}

作用:
Expense 表示持久化对象,维护业务相关数据。
InMemoryExpenseRepository 负责与底层存储(如数据库或内存)交互,确保实体的持久性。

2.3. Message-Driven Bean 对应

职责:

结合会话功能和消息驱动机制。异步接收和处理消息。

对应的组件:

在框架中,Message-Driven Bean 的功能可以通过消息队列系统(如 RabbitMQ、Kafka 等)和消费逻辑来实现。这种组件通常独立于 HTTP 请求生命周期,专注于处理异步任务。

示例:

领域事件处理器(模拟 Message-Driven Bean 的功能):

	type ExpenseMessageProcessor struct {
	    repo domain.ExpenseRepository
	}

	func NewExpenseMessageProcessor(repo domain.ExpenseRepository) *ExpenseMessageProcessor {
	    return &ExpenseMessageProcessor{repo: repo}
	}

	// 模拟异步消费逻辑
	func (p *ExpenseMessageProcessor) ProcessMessage(msg string) error {
	    // 假设消息内容包含 JSON 格式的费用数据
	    var expenseData domain.Expense
	    if err := json.Unmarshal([]byte(msg), &expenseData); err != nil {
	        return err
	    }
	    return p.repo.Save(&expenseData)
	}

消息驱动的模拟场景: 假设通过 RabbitMQ 消息队列异步传递费用记录,消费者监听并保存数据:

	func StartMessageListener(processor *ExpenseMessageProcessor) {
	    go func() {
	        for {
	            // 假设从队列中获取消息
	            msg := getMessageFromQueue() // 模拟消息队列接口
	            if err := processor.ProcessMessage(msg); err != nil {
	                log.Printf("Failed to process message: %v", err)
	            }
	        }
	    }()
	}

作用:

ExpenseMessageProcessor 接收和处理异步消息,将其转化为领域模型并保存。
消息队列模拟了异步事件的处理逻辑。

3 小结

对应关系表

EJB Bean 类型 Gin 架构中对应组件 职责与功能

Session Bean 应用层服务(ExpenseAppService) 处理短暂业务逻辑,与客户端请求生命周期一致。
Entity Bean 领域实体类(Expense)和存储库(InMemoryExpenseRepository) 表示和维护持久化数据,与底层存储交互,支持 CRUD。

Message-Driven Bean 消息处理器(ExpenseMessageProcessor) 异步接收消息并处理,将其保存为持久化对象(领域事件处理)。

优势

通过分层解耦,符合 DDD 设计思想,职责清晰。
消息驱动的异步逻辑提高了系统扩展性和性能。
与 EJB 的设计模式类似,适用于现代微服务架构中不同服务的拆分。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。