这样的时间间隔查询不仅会消耗服务器上的大量资源,还会导致网络流量超出实际需要。 尽管Java从第0天开始就支持Observer Pattern,但始终认为它不是最佳实现(请参阅Observer和Observable )。 进入JavaEE世界甚至会使事情复杂化。 但是,JavaEE6带有替代方法。
JavaEE6提供了“ @Observable”注释,作为Observer Pattern的现成的简便实现。 让我们访问上一篇文章 ,并将其扩展为使用观察者。
package com.devchronicles.observer;import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.enterprise.event.Event;
import javax.inject.Inject;/**** @author Murat Yener*/
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EventService {@Injectprivate String message;@Inject Event<String> event;public void startService(){System.out.println("start service call "+message);event.fire("this is my "+message);System.out.println("done...");}
}
将向EventService类注入String类型的Event对象,该事件对象可用于触发String对象。 如果您没有阅读上一篇文章,则message对象是一个String,它将由工厂产生并注入到EventService类中。 为简化起见,您可以在名为message的变量中键入任何字符串常量。
既然我们已经完成了可观察部分,那么现在该创建一个观察者来监听我们的事件了。
package com.devchronicles.observer;import javax.ejb.Stateless;
import javax.enterprise.event.Observes;/**** @author Murat Yener*/
@Stateless
public class EventObserver {public void doLogging(@Observes String message){System.out.println("Observed:"+message);}
}
Observes注释将方法标记为已触发的String事件的观察者。 如果运行服务器并启动start service方法,您将认识到如何将字符串神奇地注入EventService类,然后将其触发到EventObserver类将其嘲笑(观察到)的位置。 令人惊讶的是,这是在JavaEE6中实现观察者模式所需的全部。
如前所述,JavaEE6提供了一种简单的方法来实现观察者模式。 发布该帖子后,我收到了关于如何区分触发和观察到的字符串类型的几个问题。
尽管在现实世界中,您可能不会触发和观察纯字符串,但是您自己的对象将按其类型进行观察,但是区分相同类型的对象并设置不同的观察者来侦听它们仍然很容易。
首先让我们从区分纯字符串的部分开始。
package com.devchronicles.observer;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;/**** @author Murat Yener*/
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.PARAMETER})
public @interface MyEvent {Type value();enum Type{LOGGING, MESSAGE}
}
上面的接口将用作注释,以标记要触发的字符串,以后只需注释相应的部分即可观察到。
package com.devchronicles.observer;import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.enterprise.event.Event;
import javax.inject.Inject;/**** @author Murat Yener*/
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EventService {@Injectprivate String message;@Inject @MyEvent(MyEvent.Type.LOGGING)Event<String> event;@Inject @MyEvent(MyEvent.Type.MESSAGE)Event<String> anotherEvent;public void startService(){System.out.println("start service call "+message);event.fire("this is my "+message);System.out.println("done...");anotherEvent.fire("done with the service!");}
}
我们只添加具有所需类型的MyEvent批注,然后像以前一样触发事件。 标有红色的部分就是我们在上一篇文章中添加的示例。
现在让我们注释观察者部分。 同样,我们将在前面的示例中添加红色部分。
package com.devchronicles.observer;import javax.ejb.Stateless;
import javax.enterprise.event.Observes;/**** @author Murat Yener*/
@Stateless
public class EventObserver {public void doLogging(@Observes @MyEvent(MyEvent.Type.LOGGING) String message){System.out.println("Observed:"+message);}public void doLogging(@Observes @MyEvent(MyEvent.Type.MESSAGE) String message){System.out.println("Observed another type of message:"+message);}
}
那就是您甚至需要区分要观察的相同类型对象的全部。
参考: JavaEE重新审视设计模式:观察者 , JavaEE重新审视设计模式:观察器来自JCG合作伙伴 Murat Yener的Developer Chronicles博客上的第2部分 。
翻译自: https://www.javacodegeeks.com/2012/04/java-ee-revisits-design-patterns_17.html