### EJB学习笔记第六部分详解
#### 一、EJB之间的调用
EJB (Enterprise JavaBeans) 是Java EE平台中用于开发分布式企业应用程序的重要组件。在实际开发过程中,经常需要一个EJB调用另一个EJB来实现更复杂的业务逻辑。
##### 1. 采用默认的JNDI上下文对象进行查找
当两个EJB(例如EJB A和EJB B)位于同一个应用服务器上时,可以直接使用默认的JNDI上下文进行查找,而无需提供额外的JNDI入口信息。这种方式相对简单,但在JNDI名字发生改变时,代码需要调整。具体实现步骤如下:
```java
@PostConstruct
public void init() {
Context ctx = new InitialContext();
TaxRemote tr = (TaxRemote) ctx.lookup(TaxRemote.class.getName());
}
```
这里的关键在于使用`InitialContext`来获取`Context`对象,并通过`lookup`方法查找目标EJB。
##### 2. 采用`@EJB`注入另一个EJB的引用
使用`@EJB`注解可以在类级别或方法级别注入另一个EJB的引用。这种方式更为便捷,当JNDI名字发生变化时,只需修改部署描述文件(`ejb-jar.xml`)即可,无需更改代码。
示例代码如下:
```java
@EJB
private TaxRemote tr;
```
部署描述文件的配置如下:
```xml
<sun-ejb-jar>
<enterprise-beans>
<ejb>
<ejb-name>CountPriceBean</ejb-name>
<ejb-ref>
<ejb-ref-name>lab.morefunc.CountPriceBean/tr2</ejb-ref-name>
<jndi-name>lab.morefunc.TaxRemote</jndi-name>
</ejb-ref>
</ejb>
</enterprise-beans>
</sun-ejb-jar>
```
此外,还可以使用`@EJB`注解的`name`属性指定EJB引用名,例如:
```java
@EJB(name="tr2")
private TaxRemote tr2;
```
在部署描述文件中需要配置相应的`<ejb-ref-name>`。
##### 3. 使用`EJBContext`对象
这种方式相对较少使用,主要利用`EJBContext`对象先绑定后查找。`EJBContext`是由容器提供的,允许EJB实例访问EJB容器。常用的方法包括`lookup(String name)`用于查找相关资源以及`setRollbackOnly()`用于控制事务回滚。
示例代码如下:
```java
@Resource
private SessionContext sctx;
private TaxRemote tr;
@EJB(name="ejb/taxRate", beanInterface=TaxRemote.class)
private TaxRemote tr2;
```
其中`name`是EJB的引用名,`beanInterface`指定bean的类型,用于将这个bean资源绑定到对应的JNDI服务器上。
#### 二、依赖注入
依赖注入(Dependency Injection, DI)是一种设计模式,目的是减少代码间的耦合度,使得对象间的协作关系由容器来提供而不是硬编码到对象内部。在EJB中,依赖注入可以显著简化代码,提高可维护性和可测试性。
##### 举例说明
假设有一个EJB A需要使用EJB B和EJB C来完成某些任务,在传统的编程方式中,A需要自己管理B和C的生命周期,这会使得A变得复杂且难以测试。使用依赖注入之后,容器会在运行时自动将B和C注入到A中,从而简化了A的设计。
示例代码如下:
```java
@EJB
private B b;
@EJB
private C c;
```
这样,A就不必关心B和C的创建和销毁过程,只需要专注于自己的业务逻辑即可。
#### 三、EJB-jar文件的结构与配置
EJB-jar文件是包含EJB组件的归档文件,其结构通常包括:
- **业务接口的class文件**:必须包含。
- **bean类的class文件**:必须包含。
- **META-INF/标准的部署描述文件(ejb-jar.xml)**:定义EJB的配置信息。
- **META-INF/容器厂商独有的部署描述文件**:定义依赖于容器的资源(如数据源等)。
关于`ejb-jar.xml`与EJB Bean类中的注解,二者均可用于告诉容器EJB的配置信息,但优先级有所不同:
- 优先使用注解(容器会将其转换为`ejb-jar.xml`中的内容)。
- 需要修改的配置信息写在`ejb-jar.xml`中。
- 如果`ejb-jar.xml`存在,则该文件的优先级高于注解。
#### 四、Java EE企业级应用架构
Java EE(Java Platform, Enterprise Edition)是由Sun公司推出的规范,用于开发和部署多层分布式的企业级应用。典型的Java EE应用架构包括以下几层:
- **客户层**:包括Web浏览器、Applet等。
- **Web应用层**:处理HTTP请求,提供动态内容。
- **企业组件层(业务层)**:实现核心业务逻辑。
- **企业信息系统层**:访问外部系统或遗留系统。
这些层次之间通过不同的技术栈相互连接,例如:
- HTML/XML -> JSP -> EJB -> 数据库
- Java Applet -> Servlet -> EJB -> JDBC
- Web服务客户端 -> SOAP -> Web服务应用层 + 企业组件层
- JCA -> ERP/CRM系统
其中,JCA(Java Connector Architecture)用于集成ERP、CRM等后端应用系统;JMS(Java Message Service)用于实现消息传递;JNDI(Java Naming and Directory Interface)用于查找命名和服务定位。
#### 五、J2EE技术栈
Java EE技术栈非常广泛,涵盖了众多技术和标准,包括但不限于:
- **EJB**:用于构建分布式企业级应用程序。
- **JAX-WS**:用于Web服务。
- **RMI-IIOP**:用于远程方法调用。
- **JNDI**:用于查找和定位命名的服务。
- **JDBC**:用于访问关系型数据库。
- **JTA/JTS**:用于事务管理。
- **JMS**:用于消息传递。
- **Servlet**:用于处理HTTP请求。
- **JSP**:用于生成动态网页。
- **JSF**:用于构建用户界面。
- **JCA**:用于连接外部资源。
- **JAXB**:用于对象与XML之间的转换。
- **JAAS**:用于认证和授权服务。
掌握EJB之间的调用、依赖注入、EJB-jar文件的结构与配置等内容对于开发健壮的Java EE应用程序至关重要。通过理解并应用这些知识点,开发者能够构建出更为灵活、高效的企业级应用。