📄 events.html
字号:
} public void postFlush(Iterator entities) { System.out.println("Creations: " + creates + ", Updates: " + updates); } public void preFlush(Iterator entities) { updates=0; creates=0; } ...}</pre><p> 创建会话(session)的时候可以指定拦截器。 </p><pre class="programlisting">Session session = sf.openSession( new AuditInterceptor() );</pre><p> 你也可以使用<tt class="literal">Configuration</tt>来设置一个全局范围的拦截器。 </p><pre class="programlisting">new Configuration().setInterceptor( new AuditInterceptor() );</pre></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="objectstate-events"></a>13.2. 事件系统(Event system) </h2></div></div><div></div></div><p> 如果需要响应持久层的某些特殊事件,你也可以使用Hibernate3的事件框架。 该事件系统可以用来替代拦截器,也可以作为拦截器的补充来使用。 </p><p> 基本上,<tt class="literal">Session</tt>接口的每个方法都有相对应的事件。比如 <tt class="literal">LoadEvent</tt>,<tt class="literal">FlushEvent</tt>,等等(查阅XML配置文件 的DTD,以及<tt class="literal">org.hibernate.event</tt>包来获得所有已定义的事件的列表)。当某个方 法被调用时,Hibernate <tt class="literal">Session</tt>会生成一个相对应的事件并激活所 有配置好的事件监听器。系统预设的监听器实现的处理过程就是被监听的方法要做的(被监听的方法所做的其实仅仅是激活监听器, “实际”的工作是由监听器完成的)。不过,你可以自由地选择实现 一个自己定制的监听器(比如,实现并注册用来处理处理<tt class="literal">LoadEvent</tt>的<tt class="literal">LoadEventListener</tt>接口), 来负责处理所有的调用<tt class="literal">Session</tt>的<tt class="literal">load()</tt>方法的请求。 </p><p> 监听器应该被看作是单例(singleton)对象,也就是说,所有同类型的事件的处理共享同一个监听器实例,因此监听器 不应该保存任何状态(也就是不应该使用成员变量)。 </p><p> 用户定制的监听器应该实现与所要处理的事件相对应的接口,或者从一个合适的基类继承(甚至是从Hibernate自带的默认事件监听器类继承, 为了方便你这样做,这些类都被声明成non-final的了)。用户定制的监听器可以通过编程使用<tt class="literal">Configuration</tt>对象 来注册,也可以在Hibernate的XML格式的配置文件中进行声明(不支持在Properties格式的配置文件声明监听器)。 下面是一个用户定制的加载事件(load event)的监听器: </p><pre class="programlisting">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); }}</pre><p> 你还需要修改一处配置,来告诉Hibernate以使用选定的监听器来替代默认的监听器。 </p><pre class="programlisting"><hibernate-configuration> <session-factory> ... <listener type="load" class="MyLoadListener"/> </session-factory></hibernate-configuration></pre><p> 看看用另一种方式,通过编程的方式来注册它。 </p><pre class="programlisting">Configuration cfg = new Configuration();cfg.getSessionEventListenerConfig().setLoadEventListener( new MyLoadListener() );</pre><p> 通过在XML配置文件声明而注册的监听器不能共享实例。如果在多个<tt class="literal"><listener/></tt>节点中使用 了相同的类的名字,则每一个引用都将会产生一个独立的实例。如果你需要在多个监听器类型之间共享 监听器的实例,则你必须使用编程的方式来进行注册。 </p><p> 为什么我们实现了特定监听器的接口,在注册的时候还要明确指出我们要注册哪个事件的监听器呢? 这是因为一个类可能实现多个监听器的接口。在注册的时候明确指定要监听的事件,可以让启用或者禁用对某个事件的监听的配置工作简单些。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="objectstate-decl-security"></a>13.3. Hibernate的声明式安全机制 </h2></div></div><div></div></div><p> 通常,Hibernate应用程序的声明式安全机制由会话外观层(session facade)所管理。 现在,Hibernate3允许某些特定的行为由JACC进行许可管理,由JAAS进行授权管理。 本功能是一个建立在事件框架之上的可选的功能。 </p><p> 首先,你必须要配置适当的事件监听器(event listener),来激活使用JAAS管理授权的功能。 </p><pre class="programlisting"><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"/></pre><p> 接下来,仍然在<tt class="literal">hibernate.cfg.xml</tt>文件中,绑定角色的权限: </p><pre class="programlisting"><grant role="admin" entity-name="User" actions="insert,update,read"/><grant role="su" entity-name="User" actions="*"/></pre><p> 这些角色的名字就是你的JACC provider所定义的角色的名字。 </p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="transactions.html">上一页</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">上一级</a></td><td width="40%" align="right"> <a accesskey="n" href="batch.html">下一页</a></td></tr><tr><td width="40%" align="left" valign="top">第 12 章 事务和并发 </td><td width="20%" align="center"><a accesskey="h" href="index.html">起始页</a></td><td width="40%" align="right" valign="top"> 第 14 章 批量处理(Batch processing)</td></tr></table></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -