基于jsf的项目

用JSF编写的Web应用程序由相互交互的bean组成。 在开发Web应用程序时,bean之间的通信是主要的设计模式之一。 有时,一个bean需要将事件发送给其他bean,以通知它们某些更改或其他任何更改。 通常,我们可以将托管bean或Spring bean注入另一个bean的属性中,以便另一个bean可以直接通知注入的bean。 注入是好的,但是它并不是出于交流目的而引入的。 它与每个豆都不知道其他Bean的动态松耦合系统相距甚远。 在松耦合系统中,我们需要一个良好的基于​​事件的通信机制。 这篇文章将涵盖两种设计模式:观察者/事件监听器和中介者模式。 这些模式如今已在许多Web应用程序中广泛使用,但是它们具有缺点。 该系统并不是真正与它们松散耦合。 有很多更好的现代方法。 因此,我在帖子名称中写了“ Old-school approach”。 新学校的方法将在下一篇文章中公开。

观察员/事件听众
 

我们将从观察者(也称为事件监听器)模式开始。 一个称为主题或可观察对象的对象会维护其依赖项的列表(称为观察者),并自动将状态变化通知他们。 在Java中,有类java.util.Observer和java.util.Observable可以帮助实现此模式。 通过此模式进行的基于事件的通信的其他相关构造是类java.util.EventObject和接口java.util.EventListener。 让我们开始编码。 假设我们有一个I18N Web应用程序,并且用户可以在用户设置中的某处选择一种语言(语言环境)。 假设我们有一个名为UserSettingsForm的bean,它负责用户设置。 某些会话作用域的Bean可以保留I18N文本/消息,因此,当用户更改当前语言时,需要以最后选择的语言重置以前的文本/消息。 首先,我们需要一个LocaleChangeEvent。
public class LocaleChangeEvent extends EventObject {Locale locale;public LocaleChangeEvent(Object source, Locale locale) {super(source);this.locale = locale;}public Locale getLocale() {return locale;}
}

其次,我们需要一个接口LocaleChangeListener。

public interface LocaleChangeListener extends EventListener {void processLocaleChange(LocaleChangeEvent event);
}
我们的UserSettingsForm现在可以通过注册字符串并通知它们来管理LocaleChangeListener类型的实例。
@ManagedBean
@SessionScoped
public class UserSettingsForm implements Serializable {private Locale selectedLocale;private List<SelectItem> locales;private List<LocaleChangeListener> localeChangeListeners = new ArrayList<LocaleChangeListener>();public void addLocaleChangeListener(LocaleChangeListener listener) {localeChangeListeners.add(listener);}public void localChangeListener(ValueChangeEvent e) {...// notify listenersLocaleChangeEvent lce = new LocaleChangeEvent(this, this.selectedLocale);for (LocaleChangeListener lcl : localeChangeListeners) {lcl.processLocaleChange(lce);}}...
}
方法localChangeListener()是JSF ValueChangeListener,可以在例如h:selectOneMenu中应用。 每个实现LocaleChangeListener的bean都应该由UserSettingsForm注册,以便通过语言环境更改得到通知。
@ManagedBean
@SessionScoped
public MyBean implements LocaleChangeListener, Serializable {// UserSettingsForm can be injected e.g. via @ManagedProperty annotation or via Spring facilityprivate UserSettingsForm userSettingsForm;@PostConstructpublic void initialize() {userSettingsForm.addLocaleChangeListener(this);}public void processLocaleChange(LocaleChangeEvent event) {// reset something related to I18N data...}
}

根据观察者模式,UserSettingsForm是可观察的,而LocaleChangeListener的实例(如MyBean)是观察者。 讨论的模式带有一些您需要注意的重要问题。 豆紧密耦合。 有很多手动工作来重新注册bean。 Bean必须实现定义的接口。 如果您有一个通过100个语义不同的更改通知的bean,则它必须实现100个接口。 无法通知已注册的侦听器的子集–即使不需要通知所有侦听器,也总是会通知他们。 最后但并非最不重要的– 内存管理问题 。 马丁·福勒(Martin Fowler)写道: “假设我们有一些观察某些域对象的屏幕。 关闭屏幕后,我们希望将其删除,但是域对象实际上通过观察者关系携带了对屏幕的引用。 在内存管理的环境中,寿命长的域对象可能会占据很多僵尸屏幕,从而导致大量内存泄漏。”

调解员
 

与“观察者/事件侦听器”模式相比,“中介者”模式改善了基于事件的通信。 使用中介者模式,对象之间的通信将与中介者对象一起封装。 对象不再彼此直接通信,而是通过调解器进行通信。 这减少了通信对象之间的依赖性。 我们将看到它如何用于JSF-Spring Bean(在上面的示例中是标准托管Bean)。 我们将实现一个Mediator类来管理作用域Bean之间的通信。 重要的是要理解,一个bean只能通知范围更广的另一个bean。 视图作用域的bean可以通知视图作用域,会话作用域和应用程序作用域的bean,但不能请求作用域较小的作用域的bean。 请遵循此规则以避免麻烦。 这是作用域bean的一种特性–您可能还记得,可以始终将作用域更广的bean注入作用域更窄的bean中,反之亦然。 为了开始使用Mediator,我们将引入两个接口MediatorEvent,MediatorListener和中心类Mediator。
public interface MediatorEvent {...
}public interface MediatorListener {public void listenToEvent(MediatorEvent event);
}public class Mediator implements Serializable {private Collection<MediatorListener> collaborators = new HashSet<MediatorListener>();public static Mediator getCurrentInstance() {// access Mediator bean by JSF-Spring facilityreturn ContextLoader.getCurrentWebApplicationContext().getBean("mediator");}public void fireEvent(MediatorEvent event) {for (MediatorListener mediatorListener : collaborators) {mediatorListener.listenToEvent(event);}}public void addCollaborator(MediatorListener collaborator) {collaborators.add(collaborator);}public void removeCollaborator(MediatorListener collaborator) {collaborators.remove(collaborator);}
}
介体是一个有作用域的bean,可以注册并通知协作者。 合作者通过调解员进行注册。 在Spring中,bean可以实现接口InitializingBean,以便在bean实例化之后自动调用afterPropertiesSet()方法。 这类似于@PostConstruct。 afterPropertiesSet()是此类bean通过介体注册的正确位置。 Bean还应该实现MediatorListener以便被通知(请参见listenToEvent())。
public MyBean implements MediatorListener, InitializingBean, Serializable {public void afterPropertiesSet() throws Exception {...Mediator.getCurrentInstance().addCollaborator(this);}@Overridepublic void listenToEvent(MediatorEvent event) {if (event instanceof LocaleChangeEvent) {// do something}}
}
我们将在UserSettingsForm和区域设置更改中使用相同的方案。 由Mediator注册的Bean将通过fireEvent()进行通知。
public class LocaleChangeEvent implements MediatorEvent {...
}public class UserSettingsForm implements Serializable {private Locale selectedLocale;private List<SelectItem> locales;public void localChangeListener(ValueChangeEvent e) {...// notify listenersMediator.getCurrentInstance().fireEvent(new LocaleChangeEvent(this, this.selectedLocale));}...
}
调解器模式提供了豆之间更好的耦合,但是它们仍然与调解器耦合。 进一步的缺点:仍然需要手动注册bean –请参见附加代码Mediator.getCurrentInstance()。addCollaborator(this)。 每个bean仍应至少实现一个MediatorListener并带来另一个约束– listenToEvent()。 每个bean都应实现此接口方法! JSF中Mediator模式的最大缺点可能是它是有作用域的bean。 视图作用域调解器只能与视图作用域的bean一起顺利使用。 当视图作用域调解器被销毁时,注册的视图作用域Bean将自动删除。 其他情况可能会导致内存泄漏或几个问题。 例如,应通过调用removeCollaborator()手动删除由视图作用域介体注册的请求作用域Bean(很容易忘记)。 会话作用域的Bean应该由会话作用域的介体注册,否则销毁视图作用域的介体后,它们将不会得到通知。 等等
实际上,介体模式仅比常规的“观察者/事件监听器”概念好一步。 有更灵活的方法,其中“任何方法”都可以捕获引发的事件,不仅可以修复指定的问题,例如listenToEvent()。 在下一篇文章中,我们将看到简单而简单的方法,如何仅通过一种方法和其他建议来捕获乘法事件。

参考: JSF中基于事件的通信。 我们的JCG合作伙伴 Oleg Varaksin在软件开发思想博客上的老式方法 。

翻译自: https://www.javacodegeeks.com/2012/07/jsf-event-based-communication-old.html

基于jsf的项目

基于jsf的项目_JSF基于事件的沟通:过时的方法相关推荐

  1. 基于jsf的项目_JSF基于事件的交流:新派方法

    基于jsf的项目 在上一篇文章中 ,我们学习了基于Observer / Event Listener和Mediator模式的基于事件的通信. 由于它们的缺点,我想展示基于事件的通信的更有效方法. 我们 ...

  2. 项目经理如何才能做好沟通?

    很多项目经理都知道沟通是很重要的,因为项目经理工作时间中的80%左右都是在沟通,可是现实中,有多少个项目经理真正花时间去学习.去研究过沟通呢?真正了解沟通的本质与方法的项目经理又有多少呢?这就引发了一 ...

  3. JSF基于事件的交流:新派方法

    在上一篇文章中 ,我们学习了基于Observer / Event Listener和Mediator模式的基于事件的通信. 由于它们的缺点,我想展示基于事件的通信的更有效方法. 我们将从Google ...

  4. 基于JSF框架的在线棋牌游戏平台

    一.项目总体说明 1.1  项目总体说明 该项目是基于JSF框架的在线棋牌游戏平台,目前有五子棋和象棋两项已完成子模块,皆支持人机对战与在线匹配对战,其中象棋还支持大部分棋牌平台不支持的复盘功能.项目 ...

  5. 录制元素基于smartgwt框架项目如何开展自动化(一)

    时间紧张,先记一笔,后续优化与完善. 基于smartgwt框架项目如何开展自动化(一) 近来接手数据资源平台产品的自动化建立,该项目依附smartgwt框架,项目早期尝试应用watir.webdriv ...

  6. jap页面使用ajax动态加载列表数据,JSF - 使用AJAX调用基于DataTable中的mimetype值加载不同形式...

    对于我的一个项目,我需要根据DataTable组件中可用的mimetype值加载不同的表单.我有标题,内容 - 中间的DataTable和页脚中的数据显示.单击DataTable条目应根据mimety ...

  7. 基于深度学习的异构时序事件患者数据表示学习框架

    基于深度学习的异构时序事件患者数据表示学习框架 刘卢琛, 沈剑豪, 张铭,, 王子昌, 李浩然, 刘泽群 北京大学信息科学技术学院,北京 100871   摘要:患者数据的表示学习可以将患者历史信息综 ...

  8. 20个基于DPDK开源项目,建议收藏

    一.ANS – DPDK 原生加速网络堆栈 ANS(加速网络堆栈)是DPDK本地TCP/IP堆栈,也参考FreeBSD实现.ANS提供了一个与Intel DPDK一起使用的用户空间TCP/IP堆栈. ...

  9. 自动化运维-----项目实战: 基于Ansible的云平台自动化运维系统

    文章目录 项目实战: 基于Ansible的云平台自动化运维系统 一.项目介绍 1.项目介绍 2.项目背景 二.项目环境搭建 1.项目目录的配置 2.远程服务器虚拟环境的配置 3.MySQL数据库配置 ...

最新文章

  1. ROS系统 常用可视化工具的使用
  2. windows redis 客户端_redis高并发的最佳解决方案
  3. kotlin学习之数据类(七)
  4. python开发范围_Python上的字母范围
  5. composer(作曲家)安装php-ml
  6. HDU-5877-Weak Pair(树状数组+离散化+dfs)
  7. 面试精讲之面试考点及大厂真题 - 分布式专栏 05 公司使用什么RPC框架,聊聊你理解的RPC原理
  8. 文件操作fstream
  9. 以太坊合约24小时新增2.44万ETH
  10. 2020,人工智能与产业结合的新纪年,你需要哪些能力可以脱颖而出?
  11. 乐观锁、悲观锁,这一篇就够了!
  12. SqlServer两表之间:根据一个表的字段更新另一个表的字段
  13. Python使用matplotlib可视化模拟学生课程分数雷达图
  14. 课题申报书范文_教师课题申报书范例
  15. 车载高精度GNSS定位天线
  16. Linux 查看网络流量 iftop
  17. Java task类需要自己销毁_并发编程之线程创建到销毁、常用API
  18. mysql rds云数据库_云数据库 RDS MySQL快速入门手册
  19. 怎么处理视频声音变声?视频声音变声处理软件哪个好?
  20. 产品人的三个层次——老吴说产品

热门文章

  1. 经典指针程序互换(一)
  2. 19级、20级:班级日常分享,一天一瞬间
  3. 2019蓝桥杯省赛---java---B---3(数列求值)
  4. 2018蓝桥杯省赛---java---B---2(方格计数)
  5. Sring类型数组赋值
  6. 面试官角度的JVM面试
  7. 处理api返回的数据_API 乐队指挥家,网关服务正式上线
  8. java泛型程序设计——无限定通配符+通配符捕获
  9. 会话技术Session
  10. vertx rest 跨域_Vertx编程风格:您的React式Web Companion REST API解释了