一个简单的例子我们通过一个简单的例子,来介绍消息总线的使用方法。 假设这样一种场景:某公司的一位程序员进行费用申请,他申请的费用会经过所属项目组的项目经理的审批。 如果转换成消息模型那就是:“申请费用”是一个事件,而项目经理对此感兴趣。 为了让我们的视线关注于事件本身,程序代码我们尽可能的精简: <f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:w="http://www.apusic.com/jsf/widget" xmlns:layout="http://www.apusic.com/jsf/layout"
renderKitId="AJAX">
<w:page title="apply fee">
<w:form>
<layout:panelGrid columns="2">
<w:textField id="money"></w:textField>
<w:button id="apply" />
</layout:panelGrid>
</w:form>
</w:page>
</f:view>后台的 ApplyBean 代码片断如下: @ManagedBean(name="applyBean", scope=ManagedBeanScope.SESSION)
public class ApplyBean {
@Bind
private int money = 100;
@Action
public void apply(){
System.out.println("I'm a programmer, I apply " + money + " money");
}
}基于 IoVC 原理,整个页面即可运行,效果如下: ![]() 现在需要解决的问题是:当程序员调用费用申请的方法时,要能够让项目经理知道这件事情。我们做一个新的托管Bean:ProjectManagerBean,代码如下: @ManagedBean(name="projectManagerBean", scope=ManagedBeanScope.SESSION)
public class ProjectManagerBean {
private void applyFeeListener(int money) {
System.out.println("I'm your project manager, you apply " + money + " money.");
}
}那么,我们如何通过事件机制,让这apply()与 applyFeeListener(int money)两个方法关联起来呢? 首先是发送事件,我们将代码修订如下: @Action 请注意,我们增加了一个@RaiseEvent 的annotation,它的参数中:“applyFee”代表事件类型,“this.money”代表传递的参数。 ProjectManagerBean是怎样注册成为Listener的呢?
上述代码含义就是:通过@EventListener这个annotation标明:applyFeeListener方法是个事件监听器方法,并且, 它所感兴趣的事件类型是:applyFee。 好了,我们来看一下程序运行的输出结果: 2008-03-01 14:57:30 信息 [con.out] I'm a programmer, I apply 100 money 2008-03-01 14:57:30 信息 [con.out] I'm your project manager, you apply 100 money. 两者之间已经通过事件关联起来了。 现在我们需要扩展一下:除了项目经理感兴趣,部门经理对此事也感兴趣,那么,我们根本无需更改任何代码,只是新增一个新的 DepartManagerBean: @ManagedBean(name="departManagerBean", scope=ManagedBeanScope.SESSION)
public class DepartManagerBean {
@EventListener("applyFee")
private void applyFeeListener(int money) {
System.out.println("I'm your department manager, you apply " + money + " money.");
}
}程序运行的输出结果如下: 2008-03-01 15:01:03 信息 [con.out] I'm a programmer, I apply 100 money 2008-03-01 15:01:03 信息 [con.out] I'm your department manager, you apply 100 money. 2008-03-01 15:01:03 信息 [con.out] I'm your project manager, you apply 100 money. 程序员申请费用,现在项目经理和部门经理都通过事件机制知道此事了。我们希望在同一个方法中,对事件进行分类: 如果费用小于 等于100,那么,就发送一个 applyLittleFee 的事件,如果费用大于100,则发送一个 applyMuchFee 的事件;项目经理关注 applyLittleFee 事件,而部门经理关注 applyMuchFee 的事件。ApplyBean修订如下: public class ApplyBean {
@Bind
private int money = 100;
@Inject
此处的 EventBroadcaster (事件发送对象) 被注入,通过此对象,你对“发送什么事件”、“何时发送事件”都能够进行详细的控制。 ProjectManagerBean与DepartManagerBean修订如下: @ManagedBean(name="projectManagerBean", scope=ManagedBeanScope.SESSION)
public class ProjectManagerBean {
@ManagedBean(name="departManagerBean", scope=ManagedBeanScope.SESSION)
public class DepartManagerBean {
请注意,ProjectManagerBean及DepartManagerBean所感兴趣的事件也做了相应的修订,程序运行输出如下: 2008-03-01 15:10:10 信息 [con.out] I'm a programmer, I apply 100 money 2008-03-01 15:10:11 信息 [con.out] I'm your project manager, you apply 100 money. 2008-03-01 15:10:14 信息 [con.out] I'm a programmer, I apply 1000 money 2008-03-01 15:10:14 信息 [con.out] I'm your department manager, you apply 1000 money. 有时候会有这样一种需求:程序员申请费用,根据费用的大小,要自动导航到不同的页面。但有时候, 要重定向到哪些页面我们事先并不清楚。以上述场景为例:当项目经理审批时,希望导航到 projectManager.xhtml页面, 当部门经理审批时,希望导航到 departManager.xhtml页面。在 OperaMasks 2.0中,如何解决此需求? 我们首先完成这两个页面: projectManager.xhtml: <f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:w="http://www.apusic.com/jsf/widget" xmlns:layout="http://www.apusic.com/jsf/layout"
renderKitId="AJAX" xmlns:h="http://java.sun.com/jsf/html">
<w:page title="project manager">
I'm your project manager, you apply <h:outputText id="money"/> money.
</w:page>
</f:view>departManager.xhtml <f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:w="http://www.apusic.com/jsf/widget" xmlns:layout="http://www.apusic.com/jsf/layout"
renderKitId="AJAX" xmlns:h="http://java.sun.com/jsf/html">
<w:page title="project manager">
I'm your depart manager, you apply <h:outputText id="money"/> money.
</w:page>
</f:view>再对 ProjectManagerBean及DepartManagerBean修订如下: @ManagedBean(name="projectManagerBean", scope=ManagedBeanScope.SESSION)
public class ProjectManagerBean {
@Bind
private int money;
@EventListener("applyLittleFee")
private String applyFeeListener(int money) {
this.money = money;
@ManagedBean(name="DepartManagerBean", scope=ManagedBeanScope.SESSION)
public class DepartManagerBean {
@Bind
private int money;
@EventListener("applyMuchFee")
private String applyFeeListener(int money) {
this.money = money;
请注意观察:return "view:projectManager"语句中,前面的 view 意即告诉OperaMasks,这是要导航,后面的projectManager代表 view 的ID。 程序运行效果如下: ![]() ![]() 问题:如果一个事件有多个Listener,并且每个Listener都会返回“view:somePage",情况会如何?答案是:以第一个返回结果为准。 |
||
| [上一页] [下一页] | ||
事件的特性分析
@RaiseEvent("applyFee(this.money)")
public void apply(){
System.out.println("I'm a programmer, I apply " + money + " money");
}
if(money <=100) event.broadcast(this, "applyLittleFee", money);
else event.broadcast(this, "applyMuchFee", money);
}
}
