Liferay is no longer dependent on EJBs and can be deployed on a standalone servlet container. All business logic is concentrated inside POJO implementations that are looked up and instantiated by Spring. These implementations can be modified or enhanced via Spring‘s AOP and IOC capabilities.
Liferay不再依赖于EJB,它完全可以单独装配到一个servlet容器(如:Tomcat,JBoss等)中。而所有的业务逻辑都通过Spring管理的POJO来实现。这样的实现利益于Spring的AOP各IOC特性。The enterprise release of the portal wraps the POJO implementations with Session EJBs to provide heavy scaling and transaction support required by large sites. The professional release of the portal calls the POJO implementations directly to provide a light weight facade.
但在POJO的实现方法上Liferay的两个版本有所不同,企业版(enterprise)中通过EJB从而为大站点提供了高扩展性各良好的事务支持能力(如集群),而专业版(professiona)直接通过轻量级的接口完成。All data is persisted using Hibernate and is called through the POJO implementations. Liferay used to rely on CMP technology to achieve persistence, but switched over to Hibernate because of its raw speed and flexibility. Liferay is database agnostic and can run on a variety of popular
databases.
所有的业务数据都通过Hibernate来实现并通过POJO来调用。Liferay曾经使用CMP技术.来实现持久层,但后来因速度及灵活性等原因改用Hibernate。在数据库方面,Liferay也完全兼容大多数主流类型DB。Liferay uses JAAS Web security so that when a user logs in, their principal is propogated to the Servlet and EJB tiers.
Remote Session EJBs can take advantage of this by checking security and permissions at the EJB level so it does not have be duplicated else where.
Local Session EJBs exposes business logic to other Session EJBs and does not specifically check for security since they cannot be called remotely. Principals are also propagated to POJO implementations that are the base classes for
Remote Session EJBs.
Liferay使用JAAS来完成用户认证安全管理,好处是当一个用户登录后,它的安全属性可以在Servlet和EJB层中沿用,真正作到系统级的SSO。具体讲,远程EJB可以沿用安全检查及权限属性,本地的EJB是为其它EJB提供业务逻辑服务的,不能被远程调用所以也不必做此类检查;安全原则也派生到POJO实现中,而这此实现其实是远程EJB的基础类。The enterprise release uses Session EJBs which allows the deployer to separate the Web server, EJB server, and database server to achieve clustering at three levels. This is true n-tier deploying because no one is forced to cluster at any single layer and allows the most flexibility for large companies.
企业版式使用EJB,所以系统分别可以在WEB服务器、EJB服务器、数据库服务器三层中实现集群。当然在n层的系统中,集群也保持优势,而且在每一层都并不强迫使用集群,这些都为大企业应用提供了极好的弹性选择权。Most of our EJBs, HBMs, and Models are generated through the ant task
build-ejb which reads the file
ejb.xml in /portal-ejb. Each portlet that persist data has its own ejb.xml (do a search in /portal-ejb and you will get a list back). We copy this file to /portal-ejb when we want to generate the persistence classes for that portlet. This is an internal tool that is built on top of the XDoclet engine.
系统中的EJB、HBM、以及模式Model者是ant执行build-ejb任务时,通过读取目录/portal-ejb下的ejb.xml文件,然后自动生成的。每个有持久层对象的门户单元(portlet)都有自己的ejb.xml文件(可以在/portal-ejb下搜索得到清单)。当需要生成持久层的类时,就把文件复制到/portal-ejb下,这生成工具是建立在XDoclet之上的。For example, upon reading ejb.xml found in the Bookmarks portlet, the following model classes are generated. Each model class reflects a table in the database. Never edit BookmarksEntryModel. Do edit BookmarksEntry to add hand massaged code. BookmarksEntry is generated once and extends BookmarksEntryModel. This allows us the ease of generated code and flexibility of hand massaged code.
例如:通过读取Bookmarks门户单元的ejb.xml文件配置后,自动生成下列的模式类。每个类对应数据库中的一个表。永远不要手工修改BookmarksEntryModel类,而要通过修改BookmarksEntry,然后再更新BookmarksEntryModel内容。这样做的好处是减少了直接写代码的工作,而只做相应的标记工作。com.liferay.portlet.bookmarks.model.BookmarksEntrycom.liferay.portlet.bookmarks.model.BookmarksEntryModelcom.liferay.portlet.bookmarks.model.BookmarksFoldercom.liferay.portlet.bookmarks.model.BookmarksFolderModelHibernate classes are generated that map to the model classes. This allows for an n-tier architecture for cases where your model classes are marshalled across the wire and your Hibernate classes are not.
Hibernate类是根据模式(model)类对应生成的。这样就可以在多层系统中允许模式类是可作序列化处理的,而Hibernate类则不必。com.liferay.portlet.bookmarks.ejb.BookmarksEntryHBMcom.liferay.portlet.bookmarks.ejb.BookmarksFolderHBMPersistence methods to add, update, delete, find, remove, and count the Hibernate entries are generated as the default persistence mechaninsm.
持久层的方法如:add, update, delete, find, remove, 以及count,系统都默认自动生成。com.liferay.portlet.bookmarks.ejb.BookmarksEntryPersistencecom.liferay.portlet.bookmarks.ejb.BookmarksFolderPersistenceHelper classes are generated that call the persistence methods. By default, the helper classes call the Hibernate persistence methods to update the database. You can override this in
portal.properties and set your own persistence class as long as it extends the default persistence class. This means you can customize where you store your data. It can be a traditional database, a LDAP server, or even something else.
也生成了专门的协助类(Helper classes),可以用来调用持久层方法。默认时,协助类调用Hibernate的方法来对数据库进行更新操作,但是也可以改写portal.properties中的配置,使用自己专用的类来完成,但这种类要求要继承默认的持久层类。换言之,用户完全可以定制自己的持久层数据,可以是一个正统的数据库,或者是LDAP服务器,其它什么的。com.liferay.portlet.bookmarks.ejb.BookmarksEntryUtilcom.liferay.portlet.bookmarks.ejb.BookmarksFolderUtilPooling classes are also created to minimize object creation. Behavior can be modified in
portal.properties.
为了减少对象生成的成本,引入了对象池,可以通过修改portal.properties文件来控制池的基本动作。com.liferay.portlet.bookmarks.ejb.BookmarksEntryPoolcom.liferay.portlet.bookmarks.ejb.BookmarksFolderPoolPOJO implementations that extend
PrincipalBean are generated to hold business logic that check the caller principal and can be called
remotely. Calling getUserId() returns the user id of the current user. Calling getUser() returns the
User model that represents the current user. The Session EJB that extends the POJO implementation implements
PrincipalSessionBean.
用来实现业务逻辑的POJO类,通过继承PrincipalBean类,来实现有关调用者的方法,所以可以远程调用。如:调用getUserId()可以得到当前用户的ID;调用getUser()则返回当前用户的对象。EJB再继承这类POJO,实现远程调用。For example, these classes allow you to delete a bookmark entry or folder if and only if you are the creator of that entry or folder.
例如:下面的类实现了,允许当且公当bookmark项目或目录的生成者可以删除它。这些对象只有在不存在时才可能被创建。These classes are only generated once if they do not already exist.
com.liferay.portlet.bookmarks.ejb.BookmarksEntryManagerImplcom.liferay.portlet.bookmarks.ejb.BookmarksFolderManagerImplHelper classes are generated based on the POJO implementations. They help save developer time and prevent polluted code. Instead of writing many lines of code just to look up the appropriate Session EJB wrapper or POJO implementation, you simply call BookmarksEntryManagerUtil.addEntry to call the equivalent method in BookmarksEntryManagerImpl.addEntry.
协助类(Helper classes)是在POJO的实现基础上生成的。它可以节约开发者的工作,不必书写很多行的代码,而只要简单的找到合适的EJB wrapper或POJO实现,通过调用BookmarksEntryManagerUtil.addEntry来间接调用相应的BookmarksEntryManagerImpl.addEntry方法就可以了。BookmarksEntryManagerUtil calls BookmarksFolderManagerFactory to look up the class that implements BookmarksEntryManager. BookmarksFolderManagerFactory defers to Spring and settings in
portal.properties on whether to load the Session EJB wrapper or the plain POJO implementation. The Session EJB extends the POJO implementation.
BookmarksEntryManagerUtil通过调用BookmarksFolderManagerFactory来查找实现BookmarksEntryManager的类。也正是通过BookmarksFolderManagerFactory来识别Spring和portal.properties中的配置来决定要是载入EJB wrapper还是POJO实现。com.liferay.portlet.bookmarks.ejb.BookmarksEntryManagercom.liferay.portlet.bookmarks.ejb.BookmarksEntryManagerEJBcom.liferay.portlet.bookmarks.ejb.BookmarksEntryManagerEJBImplcom.liferay.portlet.bookmarks.ejb.BookmarksEntryManagerFactorycom.liferay.portlet.bookmarks.ejb.BookmarksEntryManagerHomecom.liferay.portlet.bookmarks.ejb.BookmarksEntryManagerUtilcom.liferay.portlet.bookmarks.ejb.BookmarksFolderManagercom.liferay.portlet.bookmarks.ejb.BookmarksFolderManagerEJBcom.liferay.portlet.bookmarks.ejb.BookmarksFolderManagerEJBImplcom.liferay.portlet.bookmarks.ejb.BookmarksFolderManagerFactorycom.liferay.portlet.bookmarks.ejb.BookmarksFolderManagerHomecom.liferay.portlet.bookmarks.ejb.BookmarksFolderManagerUtilTunneling classes are generated so that developers can call the POJO implementations over port 80. An example of this given in the section V of this document.
隧道类(Tunneling classes)是用来实现通过80端口来调用POJO的。在本文档的第V部分有一个例子。com.liferay.portlet.bookmarks.ejb.BookmarksEntryManagerHttpcom.liferay.portlet.bookmarks.ejb.BookmarksFolderManagerHttpSoap classes are generated so that developers can call the POJO implementations over port 80. Soap is slower than tunneling because tunneling streams requests in binary format. Soap is more flexible than tunneling because the client classes are not limited to Java.
Soap类也是用来实现通过80端口来调用POJO的。虽然与隧道类相比Soap类在速度上要差一点,原因是隧道类使用二进制数据流。但Soap类用灵活,可以适用各种客户端(不局限于Java)。com.liferay.portlet.bookmarks.ejb.BookmarksEntryManagerSoapcom.liferay.portlet.bookmarks.ejb.BookmarksFolderManagerSoapPOJO implementations classes that do
not extend
PrincipalBean are generated to hold business logic that do
not check the caller principal and can be called
locally. These classes exist so that business logic can be easily integrated with other projects.
当地的POJO为类实现,并不继承PrincipalBean类,实现业务逻辑时也不检验调用者的身份。这种类使得可以更容易地与其它的项目集成。These classes are only generated once if they do not already exist.
这些类只有在检验到不存在时才会被创建。com.liferay.portlet.bookmarks.ejb.BookmarksEntryLocalManagerImplcom.liferay.portlet.bookmarks.ejb.BookmarksFolderLocalManagerImplHelper classes are also generated.
同时协助类也生成了。com.liferay.portlet.bookmarks.ejb.BookmarksEntryLocalManagercom.liferay.portlet.bookmarks.ejb.BookmarksEntryLocalManagerEJBcom.liferay.portlet.bookmarks.ejb.BookmarksEntryLocalManagerEJBImplcom.liferay.portlet.bookmarks.ejb.BookmarksEntryLocalManagerFactorycom.liferay.portlet.bookmarks.ejb.BookmarksEntryLocalManagerHomecom.liferay.portlet.bookmarks.ejb.BookmarksEntryLocalManagerUtilcom.liferay.portlet.bookmarks.ejb.BookmarksFolderLocalManagercom.liferay.portlet.bookmarks.ejb.BookmarksFolderLocalManagerEJBcom.liferay.portlet.bookmarks.ejb.BookmarksFolderLocalManagerEJBImplcom.liferay.portlet.bookmarks.ejb.BookmarksFolderLocalManagerFactorycom.liferay.portlet.bookmarks.ejb.BookmarksFolderLocalManagerHomecom.liferay.portlet.bookmarks.ejb.BookmarksFolderLocalManagerUtilSome of our users needed to call the Local Manager classes remotely, so Remote Manager classes that parallel their Local counterparts are also generated.
但总有一些用户需要调用引种当地类,于是完全相对应的远程类也应用而生了。com.liferay.portlet.bookmarks.ejb.BookmarksEntryRemoteManagercom.liferay.portlet.bookmarks.ejb.BookmarksEntryRemoteManagerEJBcom.liferay.portlet.bookmarks.ejb.BookmarksEntryRemoteManagerEJBImplcom.liferay.portlet.bookmarks.ejb.BookmarksEntryRemoteManagerFactorycom.liferay.portlet.bookmarks.ejb.BookmarksEntryRemoteManagerHomecom.liferay.portlet.bookmarks.ejb.BookmarksEntryRemoteManagerUtilcom.liferay.portlet.bookmarks.ejb.BookmarksFolderRemoteManagercom.liferay.portlet.bookmarks.ejb.BookmarksFolderRemoteManagerEJBcom.liferay.portlet.bookmarks.ejb.BookmarksFolderRemoteManagerEJBImplcom.liferay.portlet.bookmarks.ejb.BookmarksFolderRemoteManagerFactorycom.liferay.portlet.bookmarks.ejb.BookmarksFolderRemoteManagerHomecom.liferay.portlet.bookmarks.ejb.BookmarksFolderRemoteManagerUtilA lot of people stay away from Session EJBs because they are heavy and require a lot of coding. Our build scripts show that you can leverage the advantages of Session EJBs while minimizing repetitive labor so that you can strike a good balance between effort and results.
许多人避免使用EJB,因为它的重量级,需要大量的代码工作。Liferay的自动生成脚本可以使得,既不损失EJB的优点,而且还最小化重复的代码等工作,从而你可以在努力与结果之间找到一个良好的平衡点。Spring gives Liferay additional flexibility. Developers can test their POJO implementations with Liferay Portal Professional in a servlet container and deploy to production with Liferay Portal Enterprise in an application server.