CORBA开发:工厂对象、持久化与RMI-IIOP技术解析
立即解锁
发布时间: 2025-08-20 00:52:12 订阅数: 12 

# CORBA开发:工厂对象、持久化与RMI-IIOP技术解析
## 1. 使用工厂对象创建CORBA对象
在实际应用中,客户端程序常常需要创建CORBA对象,而非仅使用已设置好的对象。创建CORBA对象的唯一途径是通过ORB上已发布的工厂对象接口。对于每种需要创建的对象类型,都必须在IDL规范(在ORB上)中定义一个工厂对象接口,并在服务器上实现该接口。通常,这类接口的命名规则是在要创建的对象类型名称后添加“Factory”一词。例如,`Account`接口的对象将由`AccountFactory`对象创建。`AccountFactory`对象包含一个创建方法,允许连接的客户端创建`Account`对象。这个创建方法的名称可以任意指定,但为了方便,通常在要创建的对象类型前加上“create”。因此,`AccountFactory`的创建方法可以命名为`createAccount`。
假设`Account`对象在创建时只需要账号和账户名,那么IDL规范中的`AccountFactory`接口如下:
```idl
interface AccountFactory
{
Account createAccount(in long acctNum,
in string acctName);
};
```
该方法的实现将使用`new`运算符来创建`Account`对象。与其他接口实现一样,此实现必须扩展由`idlj`生成的“ImplBase”类(在这种情况下是`_AccountFactoryImplBase`)。按照在实现类名称后添加“Servant”的惯例,该实现类可命名为`AccountFactoryServant`。其实现代码如下:
```java
class AccountFactoryServant
extends _AccountFactoryImplBase
{
public Account createAccount(int acctNum,
String acctName)
{
return (new AccountServant(
acctNum, acctName));
}
}
```
然而,这似乎只是将对象创建问题转移到了工厂接口上。连接的客户端无法创建工厂对象,那么它们如何访问这些对象中的创建方法呢?简单的答案是,服务器将为每个工厂接口创建一个工厂对象,并将该对象注册到ORB。客户端随后可以获取该工厂对象的引用,并使用该对象的创建方法来创建CORBA应用对象。假设客户端已获得服务器创建的`AccountFactory`对象的引用,并将该引用存储在变量`acctFactoryRef`中,客户端可以使用以下代码创建一个账号为12345、账户名为“John Andrews”的`Account`对象:
```java
Account acct = acctFactoryRef.createAccount(
12345,"John Andrews");
```
对于非持久对象,还应定义销毁CORBA对象的方法(本文暂不涉及)。
## 2. Java IDL实现库存项目管理示例
为了说明工厂接口及其关联工厂对象的使用,下面通过一个具体示例进行详细介绍。该示例展示了如何使用Java IDL提供对库存项目的平台无关访问。虽然仅使用一个库存项目进行说明,但可轻松扩展到实际应用所需的任意数量的库存项目。具体步骤如下:
### 2.1 创建IDL文件
创建一个名为`StockItem.idl`的文件,其中包含一个名为`Sales`的模块。该模块包含`StockItem`和`StockItemFactory`两个接口。`StockItem`接口包含与单个库存项目相关的属性和操作,为简化起见,属性包括库存代码和当前库存水平,操作包括增加和减少该库存项目的库存水平。由于库存代码不应更改,因此将其声明为只读属性。`StockItemFactory`接口包含`createStockItem`方法,用于创建具有指定库存代码和库存水平的`StockItem`对象。`StockItem.idl`的内容如下:
```idl
module Sales
{
interface StockItem
{
readonly attribute string code;
attribute long currentLevel;
long addStock(in long incNumber);
long removeStock(in long decNumber);
};
interface StockItemFactory
{
StockItem createStockItem(in string newCode,
in long newLevel);
};
};
```
### 2.2 编译IDL文件
由于客户端和服务器将在同一台机器上运行,因此使用`-fall`标志。执行`idlj`编译器的命令如下:
```bash
idlj –fall StockItem.idl
```
这将创建一个与模块同名的子目录(即`Sales`),其中包含以下12个文件(每个接口6个):
| 文件名称 | 说明 |
| ---- | ---- |
| `StockItem.java` | |
| `StockItemHelper.java` | |
| `StockItemHolder.java` | |
| `StockItemOperations.java` | |
| `_StockItemImplBase.java` | |
| `_StockItemStub.java` | |
| `StockItemFactory.java` | |
| `StockItemFactoryHelper.java` | |
| `StockItemFactoryHolder.java` | |
| `StockItemFactoryOperations.java` | |
| `_StockItemFactoryImplBase.java` | |
| `_StockItemFactoryStub.java` | |
### 2.3 实现接口
遵循在接口名称后添加“servant”的惯例,创建`StockItemServant`和`StockItemFactoryServant`类,分别扩展`_StockItemImplBase`和`_StockItemFactoryImplBase`类。代码如下:
```java
class StockItemServant extends _StockItemImplBase
{
//Declare and initialise instance variables…
private String code = "";
private int currentLevel = 0;
//Constructor…
public StockItemServant(String newCode, int newLevel)
{
code = newCode;
currentLevel = newLevel;
}
public int addStock(int incNumber)
{
currentLevel += incNumber;
return currentLevel;
}
public int removeStock(int decNumber)
{
currentLevel -= decNumber;
return currentLevel;
}
//Must supply following 'get' and 'set' methods…
//Accessor method ('get' method) for stock code…
public String code()
{
return code;
}
//Accessor method ('get' method) for stock level…
public int currentLevel()
{
return currentLevel;
}
//Mutator method ('set' method) for stock level…
public void currentLevel(int newLevel)
{
currentLevel = newLevel;
}
}
class StockItemFactoryServant
extends _StockItemFactoryImplBase
{
/*
Method to create a StockItemServant object and return
a reference to this object (allowing clients to
create StockItem objects from the servant)…
*/
public StockItem createStockItem(String newCode,
int newLevel)
{
return (new StockItemServant(newCode,newLevel));
}
}
```
0
0
复制全文
相关推荐










