1、定义两个接口:一个类接口和一个工厂接口,客户端通过restroy获取工厂对象的存根,再通过工厂存根获取远程对象,远程对象即使没有注册也可以远程调用
public interface ICompanyFactory extends Remote{
public ICompany getCompany(String companyName) throws RemoteException;
}
public interface ICompany extends Remote{
public String getName() throws RemoteException;//定义接口
public String getAddress() throws RemoteException;
public void setName(String name) throws RemoteException;
public void setAddress(String address) throws RemoteException;
}
2、server:
public class CompanyFactoryImpl extends UnicastRemoteObject implements ICompanyFactory{
private static final long serialVersionUID = 1L;//工厂实现类
private Map<String, ICompany> companys = null;
protected CompanyFactoryImpl() throws RemoteException {
companys = new Hashtable<String, ICompany>();
}
@Override
public ICompany getCompany(String companyName) throws RemoteException {
if(companys==null){
return null;
}
ICompany company = companys.get(companyName);
if(company!=null){
return company;
}
ICompany rsCompany = new CompanyImpl();
rsCompany.setName(companyName);
companys.put(companyName, rsCompany);
return rsCompany;
}
}
public class CompanyImpl implements ICompany {//类的实现类
private String name;
private String address;
public CompanyImpl() throws RemoteException{
UnicastRemoteObject.exportObject(this,8089);//当类已经继承了其他类时,可以使用此方式导出存根
}
@Override
public String getName() throws RemoteException {
return name;
}
@Override
public String getAddress() throws RemoteException {
return address;
}
@Override
public void setName(String name) throws RemoteException {
System.out.println("setName:"+name);
this.name = name;
}
@Override
public void setAddress(String address) throws RemoteException {
System.out.println("setAddress:"+address);
this.address = address;
}
@Override
public boolean equals(Object obj) {
System.out.println("equal....");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CompanyImpl other = (CompanyImpl) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}}
public class CompanyServer {//启动
public static void main(String[] args) {
init();
}
public static void init(){
try {
ICompanyFactory companyFactory = new CompanyFactoryImpl();
Context context = new InitialContext();
LocateRegistry.createRegistry(8089);
context.bind("rmi://127.0.0.1:8089/ICompanyFactory", companyFactory);
System.out.println("CompanyServer start success!");
} catch (RemoteException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
}
}
public class CompanyClient {
public static void main(String[] args) {
init();
}
public static void init(){
try {
Context context = new InitialContext();
ICompanyFactory companyFactory = (ICompanyFactory) context.lookup("rmi://192.168.40.69:8089/ICompanyFactory");
ICompany company1 = companyFactory.getCompany("com1");
String address1 = company1.getAddress();
if(address1==null){
company1.setAddress("address1");//调用远程set方法
}else{
System.out.println("name:"+company1.getName()+" address:"+address1);
}
ICompany company2 = companyFactory.getCompany("com1");
System.out.println((company1==company2)+"---"+company1.equals(company2));
} catch (RemoteException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
}
}
(1)、客户端每调用一次远程对象都会生成一个新的存根对象,即使调用的是同一个远程对象
(2)、存根类调用equal时(重写了equals),如果远程类时同一个远程对象则返回true,否则返回false
(3)、客户端调用setXX方法时服务器的远程对象也调用了相应的set方法,但是客户端在调用equals方法时服务器远程对象的equals方法并没有被调用,只是存根本地的equal方法的调用
(4)、远程对象跟远程注册是两个问题,远程对象说明了此对象可以被远程调用,无论他是否经过了注册;远程注册是说明了此对象经过了注册,可以在远程注册表中查找到此对象。