一、Mina中的观察者模式。
被观察者:AbstractIoService。被观察者需要有一个观察者的队列来保存观察者,该类采用了IoServiceListenerSupport这个帮助类,来保存观察者。
观察者:IoServiceListener
//直接采用匿名内部类的方式构造了IoServiceListener的观察者实例。该观察者实例只是监听service激活。
private final IoServiceListener serviceActivationListener = new IoServiceListener() {
public void serviceActivated(IoService service) {
// Update lastIoTime.
AbstractIoService s = (AbstractIoService) service;
IoServiceStatistics _stats = s.getStatistics();
_stats.setLastReadTime(s.getActivationTime());
_stats.setLastWriteTime(s.getActivationTime());
_stats.setLastThroughputCalculationTime(s.getActivationTime());
}
public void serviceDeactivated(IoService service) throws Exception {
// Empty handler
}
public void serviceIdle(IoService service, IdleStatus idleStatus) throws Exception {
// Empty handler
}
public void sessionCreated(IoSession session) throws Exception {
// Empty handler
}
public void sessionClosed(IoSession session) throws Exception {
// Empty handler
}
public void sessionDestroyed(IoSession session) throws Exception {
// Empty handler
}
};
//构造方法中将观察者添加到了观察者队列中。
protected AbstractIoService(IoSessionConfig sessionConfig, Executor executor) {
if (sessionConfig == null) {
throw new IllegalArgumentException("sessionConfig");
}
if (getTransportMetadata() == null) {
throw new IllegalArgumentException("TransportMetadata");
}
if (!getTransportMetadata().getSessionConfigType().isAssignableFrom(sessionConfig.getClass())) {
throw new IllegalArgumentException("sessionConfig type: " + sessionConfig.getClass() + " (expected: "
+ getTransportMetadata().getSessionConfigType() + ")");
}
//添加到监听队列的方法在这里!!!!!生成观察者辅助类。
listeners = new IoServiceListenerSupport(this);
listeners.add(serviceActivationListener);
// Stores the given session configuration
this.sessionConfig = sessionConfig;
// Make JVM load the exception monitor before some transports
// change the thread context class loader.
ExceptionMonitor.getInstance();
if (executor == null) {
this.executor = Executors.newCachedThreadPool();
createdExecutor = true;
} else {
this.executor = executor;
createdExecutor = false;
}
threadName = getClass().getSimpleName() + '-' + id.incrementAndGet();
}
好了,目前被观察者有了,观察者也有了,观察者也加入到了观察者队列中,下面看看被观察者被修改后,如何通知(notify)到观察者的。
因为观察者队列保存在了IoServiceListenerSupport,同时这个队列中的观察者的责任是监听Service激活,那么肯定是该类的某个方法调用了观察者的serviceActivated方法,这个方法就相当于notify了。
//notify方法。
public void fireServiceActivated() {
if (!activated.compareAndSet(false, true)) {
// The instance is already active
return;
}
activationTime = System.currentTimeMillis();
//调用了serviceActivated
for (IoServiceListener listener : listeners) {
try {
listener.serviceActivated(service);
} catch (Exception e) {
ExceptionMonitor.getInstance().exceptionCaught(e);
}
}
}
总结:这是一个比较纯粹的观察者模式。有被观察者,被观察者中有观察者队列,有通知方法。观察者继承了EventListener。