EJB初体验-概述

一、什么是EJB

EJBEnterprise JavaBeans)是使用java语言构造可移植的、可重用的和可伸缩的业务应用程序的平台。从技术上来说,EJB不是一种产品,而是Sun在Java EE中定义的一种规范,该规范制定了一系列的API。

下图是EJB提供的服务:

 


二、EJB组件类型:

EJB组件有三种类型:Session Bean、Message Drive Bean和Entity Bean


1.Session Bean 用于实现业务逻辑,分有状态的和无状态的。

当客户端请求时,容器会选择其为客户端服务,可以直接访问数据库,但更多通过Entity Bean进行访问。

(1)有状态会话Bean:会把请求同特定的客户联系起来,在客户和bean之间 建立一种一对 一的关系。例如淘宝网的购物车就是一个有状态的会话Bean。用户往购物车里加入商品,输入地址信息然后提交订单,购物车Bean维持状态,因而它知道这些变量都关联某一特定用户。 

(2)无状态会话Bean:并不知道客户或者涉及请求的上下文,从而使其成为单一请求的工具。例如:一个用户在Google中搜索关键字“Java”,客户应用程序联系一个无状态会话bean,给其传递参数,这个bean访问数据库,匹配符合检索条件的条目,并把记录传递给客户端,Bean不保留交互信息。因此,多个客户程序可以同时访问无状态会话Bean。


2.Entity Bean :表示会话终止之后持久存在的业务对象或者数据。通常作为数据库中的单一记录存在。

注意:实体Bean是EJB1.X和EJB2.X中的组件,在EJB3.X中,已经被JPA所代替。


3.Meassage Drive Bean :会话Bean和实体Bean都是以同步方式为EJB客户提供服务。客户发出请求然后等待Bean发回结果。 消息驱动Bean,采用Java消息服务JMS(Java Messaging Service),异步通信的方式,使得客户和Bean都无须依赖对方的直接响应。


三、EJB的发展史


EJB1.0:

最初版本支持有状态和无状态服务器对象(会话Bean),以及可选支持实体Bean。

优点:提供可移植性和远程特性

缺点:远程基础结构和按值传递的语义的开销大。


EJB1.1: 

要求支持实体Bean,引入XML部署描述文件


EJB2.0 

引入本地接口弥补远程接口造成的开销和按值传递的缺陷。

引入消息驱动Bean,参与异步消息系统

引入EJB查询语言EJB QL


EJB2.1

添加web服务支持

允许会话bean暴露接口

添加计时器服务

扩展EJB QL功能

引入XML schema替换 ejb-jar.xml部署文件的DTD。


EJB3.0

最重要的改动是实体Bean被替换为POJO,可以运行在EJB容器的外部

会话Bean不再需要主接口或专有的组件接口。


EJB3.1

进一步简化开发模型,最大优势声明横切方面。


总结:一说到EJB给人感觉很高大尚,并且很神秘。虽然这次项目中用到了EJB,但是目前对它的理解还是停留在神秘的阶段。通过这一个多月的项目学习, EJB给我的感受就是它封装了系统的业务逻辑,放到一个组件中,并且将这个组件部署到一个服务器上运行。



<think>我们被要求提供关于使用 camunda-ejb-client-7.17.0.jar 的解决方案。这个库通常用于在Java EE环境中通过EJB方式与Camunda BPM引擎进行交互。 主要使用场景: 1. 在远程应用服务器上调用Camunda引擎的EJB(如从Web应用调用部署在另一台服务器上的Camunda引擎) 2. 在同一个应用服务器内的不同应用模块之间通过EJB调用Camunda引擎 核心功能: - 提供EJB代理,使得调用Camunda引擎的EJB像调用本地接口一样简单 - 封装了JNDI查找和远程调用细节 使用步骤: 1. 添加依赖(Maven) 2. 配置JNDI连接 3. 获取EJB代理 4. 调用Camunda引擎API 注意:Camunda EJB Client需要与Camunda引擎的版本匹配(此处为7.17.0) 下面是一个完整的示例,展示如何使用camunda-ejb-client来启动一个流程实例。</think>### 使用 Camunda EJB Client 7.17.0 集成指南 Camunda EJB Client 是用于在 Java EE 环境中与 Camunda BPM 引擎交互的客户端库。以下是完整的集成和使用方案: #### 1. 添加 Maven 依赖 ```xml <dependency> <groupId>org.camunda.bpm</groupId> <artifactId>camunda-ejb-client</artifactId> <version>7.17.0</version> </dependency> ``` #### 2. 核心配置(ejb-jar.xml) ```xml <ejb-jar xmlns="https://jakarta.ee/xml/ns/jakartaee" version="4.0"> <enterprise-beans> <session> <ejb-name>ProcessEngineService</ejb-name> <business-remote>org.camunda.bpm.ProcessEngineService</business-remote> <ejb-class>org.camunda.bpm.client.impl.ProcessEngineServiceProxy</ejb-class> </session> </enterprise-beans> </ejb-jar> ``` #### 3. 服务端配置(camunda.xml) ```xml <bpm-platform xmlns="http://www.camunda.org/schema/1.0/BpmPlatform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.camunda.org/schema/1.0/BpmPlatform http://www.camunda.org/schema/1.0/BpmPlatform"> <process-engine name="default"> <job-executor> <job-acquisition name="default" /> </job-executor> <datasource>java:jboss/datasources/CamundaDS</datasource> <properties> <property name="history">full</property> <property name="databaseSchemaUpdate">true</property> <property name="authorizationEnabled">true</property> </properties> </process-engine> </bpm-platform> ``` #### 4. EJB 客户端使用示例 ```java import org.camunda.bpm.ProcessEngineService; import org.camunda.bpm.engine.RuntimeService; import org.camunda.bpm.engine.runtime.ProcessInstance; import javax.ejb.EJB; import javax.ejb.Stateless; import java.util.HashMap; import java.util.Map; @Stateless public class OrderProcessingService { // 注入 Camunda 引擎服务 @EJB private ProcessEngineService processEngineService; public String startOrderProcess(String orderId, double amount) { // 获取运行时服务 RuntimeService runtimeService = processEngineService .getProcessEngine("default") .getRuntimeService(); // 设置流程变量 Map<String, Object> variables = new HashMap<>(); variables.put("orderId", orderId); variables.put("amount", amount); // 启动流程实例 ProcessInstance instance = runtimeService.startProcessInstanceByKey( "orderProcessing", variables ); return instance.getId(); } } ``` #### 5. 客户端调用示例(JUnit 测试) ```java import org.camunda.bpm.ProcessEngineService; import org.junit.jupiter.api.Test; import org.apache.openejb.api.LocalClient; import javax.ejb.EJB; import javax.ejb.embeddable.EJBContainer; import java.util.Properties; @LocalClient public class OrderProcessingTest { @EJB private OrderProcessingService orderService; @Test public void testOrderProcess() throws Exception { // 配置嵌入式容器 Properties props = new Properties(); props.setProperty("openejb.configuration", "camunda.xml"); // 启动容器 try (EJBContainer container = EJBContainer.createEJBContainer(props)) { container.getContext().bind("inject", this); // 调用 EJB 服务 String processId = orderService.startOrderProcess("ORD-1001", 249.99); System.out.println("Started process: " + processId); // 这里可以添加断言验证流程状态 } } } ``` #### 6. 关键功能接口说明 | 接口 | 功能描述 | 使用场景 | |----------------------|------------------------------|------------------------------| | `ProcessEngineService` | 获取流程引擎实例 | 访问引擎API入口点 | | `RuntimeService` | 流程运行时操作 | 启动/终止流程、触发信号事件 | | `RepositoryService` | 流程部署管理 | 部署/删除流程定义 | | `TaskService` | 用户任务操作 | 认领/完成任务、设置变量 | | `HistoryService` | 历史数据访问 | 查询已完成流程实例 | #### 7. 高级功能:异步任务处理 ```java @Stateless public class PaymentProcessor { @EJB private ProcessEngineService engineService; // 监听支付任务 public void processPayment(String taskId) { TaskService taskService = engineService.getProcessEngine() .getTaskService(); // 获取任务变量 Map<String, Object> variables = taskService.getVariables(taskId); double amount = (double) variables.get("amount"); // 执行业务逻辑 boolean success = paymentGateway.charge(amount); // 完成任务 taskService.complete(taskId, Map.of("paymentSuccess", success)); } } ``` ### 常见问题解决方案 1. **ClassCastException: Cannot cast Proxy to ProcessEngineService** - 确保客户端和服务端使用相同版本的 Camunda (7.17.0) - 检查 EJB 接口是否在客户端和服务端共享 2. **NamingException: ProcessEngineService not found** ```java // 手动 JNDI 查找替代方案 ProcessEngineService service = (ProcessEngineService) new InitialContext().lookup("java:global/camunda-ejb/ProcessEngineService"); ``` 3. **事务管理** ```java @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public void startProcessInNewTransaction() { // 需要独立事务的操作 } ``` 4. **安全集成** ```java // 设置认证上下文 engineService.getProcessEngine() .getIdentityService() .setAuthentication("userId", List.of("group1"), List.of("tenant1")); ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值