📄 在ejb环境中实现“观察者”模式.htm
字号:
int count = 0; <br>
while (i.hasNext()){ <br>
ListenerSupplier listenerSupplier = (ListenerSupplier)i.next(); <br>
array[count] = listenerSupplier.getListener(publisherClass); <br>
count++; <br>
} <br>
return array; <br>
} <br>
<br>
/** <br>
* 返回当前已经为指定发布者类注册的监听器提供者副本。 <br>
* 这是一个同步方法,从而允许getListeners方法保持非同 <br>
* 步。 <br>
* @param publisherClass <br>
* @param checkInheritance 如为true,则返回为指定发布者类和它的所有父类 <br>
* 注册的监听器提供者;如为flase,则只返回为指定发布者类注册的监听 <br>
* 器提供者 <br>
* @return 相应的监听器提供者的集合(永不为null) <br>
*/ <br>
private synchronized Collection getListenerSuppliersCopy(Class <br>
publisherClass, boolean checkInheritance){ <br>
if ( checkInheritance ) { <br>
Collection publishers = myListenerSuppliersMap.keySet(); <br>
Iterator i = publishers.iterator(); <br>
Collection listenerSuppliers = new ArrayList(); <br>
while (i.hasNext()) { <br>
Class nextPublisherClass = (Class)i.next(); <br>
if ( nextPublisherClass.isAssignableFrom(publisherClass) ) { <br>
if ( myListenerSuppliersMap.get(nextPublisherClass) != null ) { <br>
listenerSuppliers.addAll((Collection) <br>
myListenerSuppliersMap.get(nextPublisherClass)); <br>
} <br>
} <br>
} <br>
return listenerSuppliers; <br>
} else { <br>
Collection listenerSuppliers = (Collection) <br>
myListenerSuppliersMap.get(publisherClass); <br>
if ( listenerSuppliers == null ) { <br>
return Collections.EMPTY_LIST; <br>
} else { <br>
//如果你决定不使用ArrayList,请改用clone支持的其他cast方式 <br>
return (ArrayList)((ArrayList)listenerSuppliers).clone(); <br>
} <br>
} <br>
} <br>
<br>
/** <br>
* 一个确保值非null的简单方法 <br>
*/ <br>
protected void assertNotNull(String message, Object object){ <br>
if ( object == null ) { <br>
throw new IllegalArgumentException(message); <br>
} <br>
} <br>
//保存“发布者类 -> 监听器提供者的集合”对 <br>
protected HashMap myListenerSuppliersMap = new HashMap(); <br>
private static DefaultListenerRegistry instance = new DefaultListenerRegistry(); <br>
} <br>
<br>
<br>
第二个提供者示例允许使用无状态会话Bean作为监听器。它用会话Bean的一个EJBHome构造,利用create()方法返回一个可用的无状态会话Bean。请注意这个提供者在WebLogic 5.1下运行,这是因为,该服务器串行化对无状态Bean的调用,不会因为同时使用同一无状态Bean而抛出RemoteException异常。 <br>
<br>
//StatelessSupplier.javapackage com.jwasp.listener; <br>
import java.util.EventListener; <br>
import javax.ejb.CreateException; <br>
import javax.ejb.EJBHome; <br>
import java.rmi.RemoteException; <br>
import java.lang.reflect.Method; <br>
import java.lang.reflect.InvocationTargetException; <br>
/** <br>
* 在getListener方法中,利用指定的监听器(无状态会话Bean) <br>
* 的EJBHome调用create()方法返回一个监听器。请确保EJB容 <br>
* 器串行化了对监听器的调用(或者在fireXXX方法中提供对监 <br>
* 听器的同步)。 <br>
*/ <br>
public class StatelessSupplier implements ListenerSupplier { <br>
public StatelessSupplier(EJBHome ejbHome) throws RemoteException{ <br>
if ( ejbHome == null ) { <br>
throw new IllegalArgumentException("EJBHome is null"); <br>
} else if ( !ejbHome.getEJBMetaData().isStatelessSession() ) { <br>
throw new IllegalArgumentException <br>
("EJBHome should belong to stateless session bean"); <br>
} <br>
myEjbHome = ejbHome; <br>
} <br>
public EventListener getListener(Class publisherClass) <br>
throws RemoteException, ListenerActivationException { <br>
try { <br>
Method createMethod = myEjbHome.getClass().getMethod("create", new Class[0]); <br>
Object object = createMethod.invoke(myEjbHome, new Object[0]); <br>
if ( object instanceof EventListener ) { <br>
return (EventListener)object; <br>
} else { <br>
throw new ListenerActivationException("Remote interface doesn't extend EventListener"); <br>
} <br>
} catch(NoSuchMethodException nsme) { <br>
throw new ListenerActivationException("Home interface doesn't define create() method"); <br>
} catch(SecurityException se) { <br>
throw new ListenerActivationException(se.getMessage()); <br>
} catch(IllegalAccessException iae) { <br>
throw new ListenerActivationException(iae.getMessage()); <br>
} catch(IllegalArgumentException iare) { <br>
throw new ListenerActivationException(iare.getMessage()); <br>
} catch(InvocationTargetException ite) { <br>
throw new ListenerActivationException(ite.getTargetException().getMessage()); <br>
} <br>
} <br>
private EJBHome myEjbHome; <br>
} <br>
<br>
<br>
■ 结束语 <br>
本文描述的框架允许你使用分布式的观察者/监听器(不错,监听器也可以是EJB;提供者将负责创建/定位EJB)。但是,它的目标不是替代JMS或消息驱动的Bean,该框架的目标是补充那两种强大的通知机制。结合JMS、消息驱动的Bean,本文描述的框架允许你在面对分布式事件发布者和监听器时,正确地实现Observer模式。 <br>
<br>
注意发布者不必一定是EJB。当发布者是普通的类时,你同样可以方便地应用本文所描述的框架。 <br>
<br>
最后,我想要指出,该框架的本质是:在发布者和观察者当时不存在的情况下,建立两者之间的关系。因此,任何想要发布者在创建时配置自己的地方,都可以使用本文所介绍的框架(如果发布者是一个EJB,则配置应该在ejbCreate()/ejbActivate()方法里进行;如果发布者是一个普通的类,则应该在构造函数里进行)。按照这种方法,如果发布者不是一个singleton,你不必担心所有的实例都有一组同样的监听器(或一组同样的实现业务逻辑的功能)。 <br>
<br>
下载本文的源代码: <br>
<br>
http://www.ccidnet.com/tech/focus/java_little_t/ImplementObserverPattern.zip<br>
<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
</p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -