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不再依賴(lài)于EJB,它完全可以單獨裝配到一個(gè)servlet容器(如:Tomcat,JBoss等)中。而所有的業(yè)務(wù)邏輯都通過(guò)Spring管理的POJO來(lái)實(shí)現。這樣的實(shí)現利益于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的實(shí)現方法上Liferay的兩個(gè)版本有所不同,企業(yè)版(enterprise)中通過(guò)EJB從而為大站點(diǎn)提供了高擴展性各良好的事務(wù)支持能力(如集群),而專(zhuān)業(yè)版(professiona)直接通過(guò)輕量級的接口完成。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.
所有的業(yè)務(wù)數據都通過(guò)Hibernate來(lái)實(shí)現并通過(guò)POJO來(lái)調用。Liferay曾經(jīng)使用CMP技術(shù).來(lái)實(shí)現持久層,但后來(lái)因速度及靈活性等原因改用Hibernate。在數據庫方面,Liferay也完全兼容大多數主流類(lèi)型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來(lái)完成用戶(hù)認證安全管理,好處是當一個(gè)用戶(hù)登錄后,它的安全屬性可以在Servlet和EJB層中沿用,真正作到系統級的SSO。具體講,遠程EJB可以沿用安全檢查及權限屬性,本地的EJB是為其它EJB提供業(yè)務(wù)邏輯服務(wù)的,不能被遠程調用所以也不必做此類(lèi)檢查;安全原則也派生到POJO實(shí)現中,而這此實(shí)現其實(shí)是遠程EJB的基礎類(lèi)。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.
企業(yè)版式使用EJB,所以系統分別可以在WEB服務(wù)器、EJB服務(wù)器、數據庫服務(wù)器三層中實(shí)現集群。當然在n層的系統中,集群也保持優(yōu)勢,而且在每一層都并不強迫使用集群,這些都為大企業(yè)應用提供了極好的彈性選擇權。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任務(wù)時(shí),通過(guò)讀取目錄/portal-ejb下的ejb.xml文件,然后自動(dòng)生成的。每個(gè)有持久層對象的門(mén)戶(hù)單元(portlet)都有自己的ejb.xml文件(可以在/portal-ejb下搜索得到清單)。當需要生成持久層的類(lèi)時(shí),就把文件復制到/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.
例如:通過(guò)讀取Bookmarks門(mén)戶(hù)單元的ejb.xml文件配置后,自動(dòng)生成下列的模式類(lèi)。每個(gè)類(lèi)對應數據庫中的一個(gè)表。永遠不要手工修改BookmarksEntryModel類(lèi),而要通過(guò)修改BookmarksEntry,然后再更新BookmarksEntryModel內容。這樣做的好處是減少了直接寫(xiě)代碼的工作,而只做相應的標記工作。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類(lèi)是根據模式(model)類(lèi)對應生成的。這樣就可以在多層系統中允許模式類(lèi)是可作序列化處理的,而Hibernate類(lèi)則不必。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,系統都默認自動(dòng)生成。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.
也生成了專(zhuān)門(mén)的協(xié)助類(lèi)(Helper classes),可以用來(lái)調用持久層方法。默認時(shí),協(xié)助類(lèi)調用Hibernate的方法來(lái)對數據庫進(jìn)行更新操作,但是也可以改寫(xiě)portal.properties中的配置,使用自己專(zhuān)用的類(lèi)來(lái)完成,但這種類(lèi)要求要繼承默認的持久層類(lèi)。換言之,用戶(hù)完全可以定制自己的持久層數據,可以是一個(gè)正統的數據庫,或者是LDAP服務(wù)器,其它什么的。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.
為了減少對象生成的成本,引入了對象池,可以通過(guò)修改portal.properties文件來(lái)控制池的基本動(dòng)作。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.
用來(lái)實(shí)現業(yè)務(wù)邏輯的POJO類(lèi),通過(guò)繼承PrincipalBean類(lèi),來(lái)實(shí)現有關(guān)調用者的方法,所以可以遠程調用。如:調用getUserId()可以得到當前用戶(hù)的ID;調用getUser()則返回當前用戶(hù)的對象。EJB再繼承這類(lèi)POJO,實(shí)現遠程調用。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.
例如:下面的類(lèi)實(shí)現了,允許當且公當bookmark項目或目錄的生成者可以刪除它。這些對象只有在不存在時(shí)才可能被創(chuàng )建。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.
協(xié)助類(lèi)(Helper classes)是在POJO的實(shí)現基礎上生成的。它可以節約開(kāi)發(fā)者的工作,不必書(shū)寫(xiě)很多行的代碼,而只要簡(jiǎn)單的找到合適的EJB wrapper或POJO實(shí)現,通過(guò)調用BookmarksEntryManagerUtil.addEntry來(lái)間接調用相應的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通過(guò)調用BookmarksFolderManagerFactory來(lái)查找實(shí)現BookmarksEntryManager的類(lèi)。也正是通過(guò)BookmarksFolderManagerFactory來(lái)識別Spring和portal.properties中的配置來(lái)決定要是載入EJB wrapper還是POJO實(shí)現。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.
隧道類(lèi)(Tunneling classes)是用來(lái)實(shí)現通過(guò)80端口來(lái)調用POJO的。在本文檔的第V部分有一個(gè)例子。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類(lèi)也是用來(lái)實(shí)現通過(guò)80端口來(lái)調用POJO的。雖然與隧道類(lèi)相比Soap類(lèi)在速度上要差一點(diǎn),原因是隧道類(lèi)使用二進(jìn)制數據流。但Soap類(lèi)用靈活,可以適用各種客戶(hù)端(不局限于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為類(lèi)實(shí)現,并不繼承PrincipalBean類(lèi),實(shí)現業(yè)務(wù)邏輯時(shí)也不檢驗調用者的身份。這種類(lèi)使得可以更容易地與其它的項目集成。These classes are only generated once if they do not already exist.
這些類(lèi)只有在檢驗到不存在時(shí)才會(huì )被創(chuàng )建。com.liferay.portlet.bookmarks.ejb.BookmarksEntryLocalManagerImplcom.liferay.portlet.bookmarks.ejb.BookmarksFolderLocalManagerImplHelper classes are also generated.
同時(shí)協(xié)助類(lèi)也生成了。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.
但總有一些用戶(hù)需要調用引種當地類(lèi),于是完全相對應的遠程類(lèi)也應用而生了。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的自動(dòng)生成腳本可以使得,既不損失EJB的優(yōu)點(diǎn),而且還最小化重復的代碼等工作,從而你可以在努力與結果之間找到一個(gè)良好的平衡點(diǎn)。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.