Liferay Portal 系统架构点滴 原文地址: http://www.liferay.com/web/guest/documentation/architecture
目录 Liferay Portal 系统架构点滴......................................................................................................1 目录...........................................................................................................................................1 I、综述.....................................................................................................................................1 II、Portlet 应用接口(JSP168)...........................................................................................2 III、Struts 和 Tiles...........................................................................................................2 IV、Session EJBs、Spring 和 Hibernate...........................................................................3 V、SAOP、RMI 和 Tunneling...................................................................................................5 VI 应用服务器.........................................................................................................................6
I、综述 用户可以通过传统的或者无线网络的方式访问 portal。开发者可以通过 SOAP、RMI 和 自己定义的通道类访问暴露的 API 来操作 portal。
II、Portlet 应用接口(JSP168) Liferay 设计成为部署符合(JSP168)Portlet 应用接口的 Portlet。很多有用的 Portlet(比如 邮件、Liferay 文档、日立、公告版和其他)已经跟 portal 绑定,而且可以作为添加自定义的 Portlet 的范例。
III、Struts 和 Tiles 所有的 HTTP 和 WAP 请求都通过 MainServlet 响应,MailServlet 扩展了 Struts 基类 ActionServlet。 MainServlet 处理所有的请求,使得每个请求都路由到合适的 PortletAction。 想要更好的理解 portal 的 web 框架请参考 Struts。 Portal 的布局信息通过定制的模板管理。想要更好的理解 Tiles 如何管理布局的,请参 考 Tile 的相关文章。
IV、Session EJBs、Spring 和 Hibernate Liferay 不再依赖 EBJ,可以部署在标准的 servlet 容器中。所有的业务逻辑都集中在可 以被 Spring 查找和实例化的 POJO 实现中。这些实现都可以通过 Spring 的 AOP 和 IOC 修改 或者强化。 Portal 企业版使用 Session EJB 包装 POJO 实现,以为大型网站提供所需的重量级扩展 和事务支持。Portal 专业版调用 POJO 实现以提供轻量级的一致的外观(façade)。 所有的数据都使用 Hibernate 持久化,供 POJO 实现调用。 Liferay 原来使用 CMP 技术 构建持久化, 因为 Hibernate 优秀的速度和弹性而转换为 Hibernate。 Liferay 不依赖特定的 数据库,可以在多种流行的数据库上运行。 Liferay 使用 JAAS Web 安全机制,当用户登录的时候,他们的信息会被传送到相应的 Servlet 和 EJB 节点。远程的 Session EJB 可以利用这一点,在 EJB 层级确认安全性和授权, 防止它在其他地方被复制。本地 Session EJB 向其他 Session EJB 暴露业务逻辑,不需要明确 的确认安全性,因为它们不会被远程调用。信息也会被传送到作为远程 Session EJB 基础类 的 POJO 实现上。 企业版使用 Session EJB,允许部署者将 Web 服务器、EJB 服务器、数据库服务器分开, 构建三层的架构。这是真正的 N 层部署,因为没有人再关注单层的群,而且可以为大企业 提供最大程度的弹性。 大部分的 EJB、HBM 和 Model 都是用/portal-ejb 目录下 service。xml 中的 ant 任务 build-service 生成的。每个持久化数据的 Portlet 都有自己的 service。xml。(搜索/portal-ejb 目录,你就可以得到一个列表)。当我们想要为 portlet 产生持久类的时候就可以复制这些文 件到/portal-ejb 目录。这是一个构建在 Xdoclet 引擎上面的内部工具。 比如,在读取 Bookmarks Portlet 的 service。xml 时,下列模型类被生成。每个模型类映 射数据库中的一个表。不要编辑 BookmarksEntryModel,要通过编辑 BookmarksEntry 来增加 手工维护的代码。BookmarksEntry 一次性生成,扩展了 BookmarksEntryModel。这样允许我 们轻松的生成代码,而且具备手工维护的弹性。 com.liferay.portlet.bookmarks.model.BookmarksEntry com.liferay.portlet.bookmarks.model.BookmarksEntryModel com.liferay.portlet.bookmarks.model.BookmarksFolder com.liferay.portlet.bookmarks.model.BookmarksFolderModel
Hibernate 类生成针对各个模型类的映射。这样当模型类跨层配置而 Hibernate 不是的时 候允许一个 N 层的架构。 com.liferay.portlet.bookmarks.service.persistence.BookmarksEntryHBM com.liferay.portlet.bookmarks.service.persistence.BookmarksFolderHBM
添加、更新、删除、查找、移动和计算 Hibernate entries 的持久方法作为默认的持久化 机制被生成。 com.liferay.portlet.bookmarks.service.persistence.BookmarksEntryPersistence com.liferay.portlet.bookmarks.service.persistence.BookmarksFolderPersistence
生成的帮助类调用持久化方法。默认的,帮助类调用 Hibernate 持久化方法来更新数据 库。你可以在 portal。properties 中重写,而且只要扩展了默认的持久化类就可以设置自己的 持久化类。这意味着可以自定义在哪里保存你的数据。它可以是一个传统的数据库,或者 LDAP 服务器,或者其他。 com.liferay.portlet.bookmarks.service.persistence.BookmarksEntryUtil com.liferay.portlet.bookmarks.service.persistence.BookmarksFolderUtil
池类也被创建成最小的对象,行为也可以在 portal。properties 中修改。 com.liferay.portlet.bookmarks.service.persistence.BookmarksEntryPool com.liferay.portlet.bookmarks.service.persistence.BookmarksFolderPool
扩展了 PrincipalBean 的 POJO 实现持有业务逻辑,确认调用者信息,可以被远程调用。 调用 getUserId()返回当前用户 id。调用 getUser()返回代表当前用户的用户模型。扩展 POJO 实现的 Session EJB 实现了 PrincipalSessionBean。 比如,这些类允许你删除一个书签入口或者文件夹,当且仅当你是这个入口或者文件夹 的创建者。 这些类只有在它们不存在的时候才能被生成。 com.liferay.portlet.bookmarks.service.impl.BookmarksEntryServiceImpl com.liferay.portlet.bookmarks.service.impl.BookmarksFolderServiceImpl
帮助类是基于 POJO 实现生成的。它们帮助保存开发者的时间和显示错误(polluted)的代 码。与其写好几行代码来寻找合适的 Session EJB 包装或者 POJO 实现,你可以简单的使用 BookmarksEntryServiceUril。addEntry 来调用 BookmarksEntryServiceImpl。addEntry 中的等 价方法。 BookmarksEntryServiceUril 调 用 BookmarksFolderServiceFactory 来 查 找 实 现 BookmarksEntryService 的类。BookmarksFolderServicesFactory 根据 Spring 和 portal。properties 的配置来决定是否加载 Session EJB 包装或者 POJO 实现。Session EJB 扩展了 POJO 实现。 com.liferay.portlet.bookmarks.service.ejb.BookmarksEntryServiceEJB com.liferay.portlet.bookmarks.service.ejb.BookmarksEntryServiceEJBImpl com.liferay.portlet.bookmarks.service.ejb.BookmarksEntryServiceHome com.liferay.portlet.bookmarks.service.spring.BookmarksEntryService com.liferay.portlet.bookmarks.service.spring.BookmarksEntryServiceFactory com.liferay.portlet.bookmarks.service.spring.BookmarksEntryServiceUtil com.liferay.portlet.bookmarks.service.ejb.BookmarksFolderServiceEJB com.liferay.portlet.bookmarks.service.ejb.BookmarksFolderServiceEJBImpl com.liferay.portlet.bookmarks.service.ejb.BookmarksFolderServiceHome com。Liferay.portlet.bookmarks.service.spring.BookmarksFolderService com。Liferay.portlet.bookmarks.service.spring.BookmarksFolderServiceFactory com。Liferay.portlet.bookmarks.service.spring.BookmarksFolderServiceUtil
通道(Tunneling)类使得开发者可以通过 80 端口调用 POJO 实现。本文档的 V 部分针对 这个给出了一个例子。 com.liferay.portlet.bookmarks.service.http.BookmarksEntryServiceHttp com.liferay.portlet.bookmarks.service.http.BookmarksFolderServiceHttp
Soap 类被生成,以便开发者通过 80 端口调用 POJO 实现。Soap 比通道(tunneling)慢, 因为 tunneling 请求流是二进制格式的。Soap 比 tunneling 灵活,因为客户端类不局限于 Java。 com.liferay.portlet.bookmarks.service.http.BookmarksEntryServiceSoap com.liferay.portlet.bookmarks.service.http.BookmarksFolderServiceSoap
没有扩展 PrincipalBean 的 POJO 实现类用来持有业务逻辑,不用确认调用者的信息, 可以被本地调用。这些类的存在使得业务逻辑可以很容易的被其他工程集成。 这些类只有在先前不存在的情况下才会被生成。
com.liferay.portlet.bookmarks.service.impl.BookmarksEntryLocalServiceImpl com.liferay.portlet.bookmarks.service.impl.BookmarksFolderLocalServiceImpl
帮助类也一并生成。 com.liferay.portlet.bookmarks.service.ejb.BookmarksEntryLocalServiceEJB com.liferay.portlet.bookmarks.service.ejb.BookmarksEntryLocalServiceEJBImpl com.liferay.portlet.bookmarks.service.ejb.BookmarksEntryLocalServiceHome com.liferay.portlet.bookmarks.service.spring.BookmarksEntryLocalService com.liferay.portlet.bookmarks.service.spring.BookmarksEntryLocalServiceFactory com.liferay.portlet.bookmarks.service.spring.BookmarksEntryLocalServiceUtil com.liferay.portlet.bookmarks.service.ejb.BookmarksFolderLocalServiceEJB com.liferay.portlet.bookmarks.service.ejb.BookmarksFolderLocalServiceEJBImpl com.liferay.portlet.bookmarks.service.ejb.BookmarksFolderLocalServiceHome com.liferay.portlet.bookmarks.service.spring.BookmarksFolderLocalService com.liferay.portlet.bookmarks.service.spring.BookmarksFolderLocalServiceFactory com.liferay.portlet.bookmarks.service.spring.BookmarksFolderLocalServiceUtil
有一些用户需要远程调用本地的 Service 类,所以远程 Service 类的本地副本也一并被生 成。 com.liferay.portlet.bookmarks.service.ejb.BookmarksEntryRemoteServiceEJB com.liferay.portlet.bookmarks.service.ejb.BookmarksEntryRemoteServiceEJBImpl com.liferay.portlet.bookmarks.service.ejb.BookmarksEntryRemoteServiceHome com.liferay.portlet.bookmarks.service.spring.BookmarksEntryRemoteService com.liferay.portlet.bookmarks.service.spring.BookmarksEntryRemoteServiceFactory com.liferay.portlet.bookmarks.service.spring.BookmarksEntryRemoteServiceUtil com.liferay.portlet.bookmarks.service.ejb.BookmarksFolderRemoteServiceEJB com.liferay.portlet.bookmarks.service.ejb.BookmarksFolderRemoteServiceEJBImpl com.liferay.portlet.bookmarks.service.ejb.BookmarksFolderRemoteServiceHome com.liferay.portlet.bookmarks.service.spring.BookmarksFolderRemoteService com.liferay.portlet.bookmarks.service.spring.BookmarksFolderRemoteServiceFactory com.liferay.portlet.bookmarks.service.spring.BookmarksFolderRemoteServiceUtil
很多人刻意避免 Session EJB 因为它很重和需要大量的编码。我们的构建脚本证明你可 以在复用中保持 Session EBJ 的优势,这样可以在付出和回报上保持很好平衡。 Spring 给予 Liferay 额外的弹性。 开发者利用 Liferay Portal,可以在一个 Servlet 容器中 测试他们的 POJO 实现;而利用 Liferay Portal 企业版,可以在一个应用服务器部署成产品。
V、SAOP、RMI 和 Tunneling 所有的远程 POJO 实现都通过 SOAP、RMI 和我们自己的通道(Tunneling)类暴露给外部 世界。
我们并不是简单的这样做因为 Web Service 还是一个困顿(buzz)的世界,但是我们发现 它确实对集成有用。接下来是一个公司平衡这些资源的例子。 3 sixteen 是一家将快速创建和运作的 T 恤公司。他们看到 Liferay,想利用集成的购物 portlet。但是他们认为 Liferay 作为一个处于时尚前沿的 T 恤公司站点太难看了。为了解决 这个问题,他们决定将他们的网站分为两个站点:一个手册站点和一个购物站点。 www。3sixteen。com 成为一个构建在 Flash 上面的漂亮的站点。my。3sixteen。com 则 是使用 Liferay 分发的购物站点。这两个站点分别放在不同的 Linux 系统主机上,所有的目 的放在不同的宿主上。 他们还需要构建一个邮件列表来收集所有感兴趣的客户的邮件地址。为实现这个,他们 再 Flash 站点增加了一个 JSP 弹出窗口(pop up box),这样可以告诉 Portal 服务器在 Address Book Portlet 中将邮件地址增加到联系列表(contact)。 下面是一个 JSP 片断,显示 3sixteen 的用户如何利用 ABContactServiceHttp 增加一个联 系列表。 String URL = "http://my。3sixteen。com"; HttpPrincipal httpPrincipal = new HttpPrincipal(URL, "joe_bloggs", "password"); ABContactServiceHttp。addContact(httpPrincipal, firstName, lastName, emailAddress); ABContactServiceHttp调用ABContactServiceUtil的addContact。这个调用通过 80 端口发 送,被http://my。3sixteen。com/tunnel/servlet/AuthTunnelServlet接收。应用服务器确认认证 匹配,然后处理ABContactServiceUtil,就好像ID为joe_bloggs的用户在调用addContact。然后 ABContactServiceUtil调用ABContactServiceImpl来完成实际工作。你可以通过查看JavaDocs 里面的源代码来查看这个逻辑。 现在 Joe Bloggs 可以登录到 portal,在 Address Book portlet 可以看到他已经有一个新的 联系列表。所有被包含的 portlet 都有这个性能因为这些帮助类已经生成。这意味着你可以 撰写 applet 或者任何 Java 应用来操作那些包含你的业务逻辑的 Session EJB。假如有人持有 你的密码那么这会是一个安全问题,所以你可以通过修改配置文件 portal。properties 来限制 通道(Tunnel)Servlet 只监听特定的端口。 你也可以通过 SOAP 和 RMI 操作 Session EJB。我们将尽快提交更多这方面的例子。
VI 应用服务器 Liferay 是从底层构建的,可以被应用服务器所用。下面是一个 Portal 例子列表,显示 portal 连接数据库以及展示 Liferay 的性能。 http://demo.liferay.net http://my.ccuc.net http://my.3sixteen.com http://portal.liferay.com http://www.gatewayfriends.org http://www.jasonandiris.com
每个 Portal 中的用户在其他 Portal 中没有信息保留。他们用域名分隔开,根据公司编号 存在于各自的空间内。 查看 Multiple Portal 获取细节信息,了解如何在一台机器上部署多个 Portal 实例。
作者 : eamoi @ Aljoin Software Dev2dev ID: educhina Blog 地址: http://spaces.msn.com/members/eamoi/ http://blog.sina.com.cn/u/1183534285 http://www.blogjava.net/eamoi/