国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
第?13?章? 攔截器與事件(Interceptors and events)

第 13 章 攔截器與事件(Interceptors and events)

應(yīng)用程序能夠響應(yīng)Hibernate內(nèi)部產(chǎn)生的特定事件是非常有用的。這樣就允許實現(xiàn)某些通用的功能以及允許對Hibernate功能進行擴展。

13.1. 攔截器(Interceptors)

Interceptor接口提供了從會話(session)回調(diào)(callback)應(yīng)用程序(application)的機制,這種回調(diào)機制可以允許應(yīng)用程序在持久化對象被保存、更新、刪除或是加載之前,檢查并(或)修改其屬性。一個可能的用途,就是用來跟蹤審核(auditing)信息。例如:下面的這個攔截器,會在一個實現(xiàn)了Auditable接口的對象被創(chuàng)建時自動地設(shè)置createTimestamp屬性,并在實現(xiàn)了Auditable接口的對象被更新時,同步更新lastUpdateTimestamp屬性。

package org.hibernate.test;

import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;

import org.hibernate.Interceptor;
import org.hibernate.type.Type;

public class AuditInterceptor implements Interceptor, Serializable {

private int updates;
private int creates;

public void onDelete(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
// do nothing
}

public boolean onFlushDirty(Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) {

if ( entity instanceof Auditable ) {
updates++;
for ( int i=0; i < propertyNames.length; i++ ) {
if ( "lastUpdateTimestamp".equals( propertyNames[i] ) ) {
currentState[i] = new Date();
return true;
}
}
}
return false;
}

public boolean onLoad(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
return false;
}

public boolean onSave(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {

if ( entity instanceof Auditable ) {
creates++;
for ( int i=0; i<propertyNames.length; i++ ) {
if ( "createTimestamp".equals( propertyNames[i] ) ) {
state[i] = new Date();
return true;
}
}
}
return false;
}

public void postFlush(Iterator entities) {
System.out.println("Creations: " + creates + ", Updates: " + updates);
}

public void preFlush(Iterator entities) {
updates=0;
creates=0;
}

...

}

創(chuàng)建會話(session)的時候可以指定攔截器。

Session session = sf.openSession( new AuditInterceptor() );

你也可以使用Configuration來設(shè)置一個全局范圍的攔截器。

new Configuration().setInterceptor( new AuditInterceptor() );

13.2. 事件系統(tǒng)(Event system)

如果需要響應(yīng)持久層的某些特殊事件,你也可以使用Hibernate3的事件框架。該事件系統(tǒng)可以用來替代攔截器,也可以作為攔截器的補充來使用。

基本上,Session接口的每個方法都有相對應(yīng)的事件。比如LoadEventFlushEvent,等等(查閱XML配置文件的DTD,以及org.hibernate.event包來獲得所有已定義的事件的列表)。當(dāng)某個方法被調(diào)用時,Hibernate Session會生成一個相對應(yīng)的事件并激活所有配置好的事件監(jiān)聽器。系統(tǒng)預(yù)設(shè)的監(jiān)聽器實現(xiàn)的處理過程就是被監(jiān)聽的方法要做的(被監(jiān)聽的方法所做的其實僅僅是激活監(jiān)聽器,“實際”的工作是由監(jiān)聽器完成的)。不過,你可以自由地選擇實現(xiàn)一個自己定制的監(jiān)聽器(比如,實現(xiàn)并注冊用來處理處理LoadEventLoadEventListener接口),來負責(zé)處理所有的調(diào)用Sessionload()方法的請求。

監(jiān)聽器應(yīng)該被看作是單例(singleton)對象,也就是說,所有同類型的事件的處理共享同一個監(jiān)聽器實例,因此監(jiān)聽器不應(yīng)該保存任何狀態(tài)(也就是不應(yīng)該使用成員變量)。

用戶定制的監(jiān)聽器應(yīng)該實現(xiàn)與所要處理的事件相對應(yīng)的接口,或者從一個合適的基類繼承(甚至是從Hibernate自帶的默認事件監(jiān)聽器類繼承,為了方便你這樣做,這些類都被聲明成non-final的了)。用戶定制的監(jiān)聽器可以通過編程使用Configuration對象來注冊,也可以在Hibernate的XML格式的配置文件中進行聲明(不支持在Properties格式的配置文件聲明監(jiān)聽器)。下面是一個用戶定制的加載事件(load event)的監(jiān)聽器:

public class MyLoadListener extends DefaultLoadEventListener {
// this is the single method defined by the LoadEventListener interface
public Object onLoad(LoadEvent event, LoadEventListener.LoadType loadType)
throws HibernateException {
if ( !MySecurity.isAuthorized( event.getEntityClassName(), event.getEntityId() ) ) {
throw MySecurityException("Unauthorized access");
}
return super.onLoad(event, loadType);
}
}

你還需要修改一處配置,來告訴Hibernate以使用選定的監(jiān)聽器來替代默認的監(jiān)聽器。

<hibernate-configuration>
<session-factory>
...
<listener type="load" class="MyLoadListener"/>
</session-factory>
</hibernate-configuration>

看看用另一種方式,通過編程的方式來注冊它。

Configuration cfg = new Configuration();
cfg.getSessionEventListenerConfig().setLoadEventListener( new MyLoadListener() );

通過在XML配置文件聲明而注冊的監(jiān)聽器不能共享實例。如果在多個<listener/>節(jié)點中使用了相同的類的名字,則每一個引用都將會產(chǎn)生一個獨立的實例。如果你需要在多個監(jiān)聽器類型之間共享監(jiān)聽器的實例,則你必須使用編程的方式來進行注冊。

為什么我們實現(xiàn)了特定監(jiān)聽器的接口,在注冊的時候還要明確指出我們要注冊哪個事件的監(jiān)聽器呢?這是因為一個類可能實現(xiàn)多個監(jiān)聽器的接口。在注冊的時候明確指定要監(jiān)聽的事件,可以讓啟用或者禁用對某個事件的監(jiān)聽的配置工作簡單些。

13.3. Hibernate的聲明式安全機制

通常,Hibernate應(yīng)用程序的聲明式安全機制由會話外觀層(session facade)所管理?,F(xiàn)在,Hibernate3允許某些特定的行為由JACC進行許可管理,由JAAS進行授權(quán)管理。本功能是一個建立在事件框架之上的可選的功能。

首先,你必須要配置適當(dāng)?shù)氖录O(jiān)聽器(event listener),來激活使用JAAS管理授權(quán)的功能。

<listener type="pre-delete" class="org.hibernate.secure.JACCPreDeleteEventListener"/>
<listener type="pre-update" class="org.hibernate.secure.JACCPreUpdateEventListener"/>
<listener type="pre-insert" class="org.hibernate.secure.JACCPreInsertEventListener"/>
<listener type="pre-load" class="org.hibernate.secure.JACCPreLoadEventListener"/>

接下來,仍然在hibernate.cfg.xml文件中,綁定角色的權(quán)限:

<grant role="admin" entity-name="User" actions="insert,update,read"/>
<grant role="su" entity-name="User" actions="*"/>

這些角色的名字就是你的JACC provider所定義的角色的名字。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Hibernate 的工具類
Hibernate回調(diào)與攔截機制
Hibernate 攔截器
Hibernate 通用的添加實體方法
Struts2攔截器和監(jiān)聽器
servlet,過濾器,監(jiān)聽器,攔截器的區(qū)別
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服