根据hibernate拦截器实现可配置日志的记录

时间:2021-06-13 16:06:15

对于日志和事件的记录在每个项目中都会用到,如果在每个manager层中触发时间记录的话,会比较难以扩展和维护,所以可配置的日志和事件记录在项目中会用到!

首先在spring的配置文件中加入hibernate拦截器

Java代码 根据hibernate拦截器实现可配置日志的记录
  1. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">   
  2.     <property name="entityInterceptor">   
  3.                 <ref bean="myInterceptor"/>   
  4.     </property>   
  5. </bean>   
  6.   
  7.   
  8. <bean id="myInterceptor" class="com.creawor.cbsms.util.MyInterceptor" />  
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="entityInterceptor"> <ref bean="myInterceptor"/> </property> </bean> <bean id="myInterceptor" class="com.creawor.cbsms.util.MyInterceptor" />

 MyInterceptor拦截器为:

Java代码 根据hibernate拦截器实现可配置日志的记录
  1. package com.creawor.cbsms.util;   
  2.   
  3. import java.io.Serializable;   
  4. import java.lang.reflect.InvocationTargetException;   
  5. import java.lang.reflect.Method;   
  6. import java.util.Iterator;   
  7.   
  8. import javacommon.util.ApplicationContextHolder;   
  9.   
  10. import org.hibernate.CallbackException;   
  11. import org.hibernate.EntityMode;   
  12. import org.hibernate.Interceptor;   
  13. import org.hibernate.Transaction;   
  14. import org.hibernate.type.Type;   
  15.   
  16. import com.creawor.cbsms.event.EventRecord;   
  17. import com.creawor.cbsms.model.CbsChannel;   
  18. import com.creawor.cbsms.model.CbsMessage;   
  19.   
  20.   
  21. public class MyInterceptor implements Interceptor{   
  22.   
  23.   
  24.      //删除时记录时间   
  25.     public void onDelete(Object obj, Serializable arg1, Object[] arg2, String[] arg3, Type[] arg4) throws CallbackException {   
  26.         // TODO Auto-generated method stub  
  27.         String[] entitys EventRecord.getDeleteEntitysFireEvent();   
  28.         for (String entityName entitys) {   
  29.             if (entityName.equals(obj.getClass().getSimpleName())) {   
  30.                 getEventRecordMethod(entityName, obj,EventRecord.getDeleteInfo());   
  31.             }   
  32.         }   
  33.   
  34.     }   
  35.                 //修改时记录事件  
  36.      public boolean onFlushDirty(Object obj, Serializable id, Object[] currentState, Object[] previousState String[] propertyNames, Type[] types){   
  37.        
  38.         String[] entitys EventRecord.getUpdateEntitysFireEvent();   
  39.         for (String entityName entitys) {   
  40.             if (entityName.equals(obj.getClass().getSimpleName())) {   
  41.                 getEventRecordMethod(entityName, obj, EventRecord.getUpdateInfo());   
  42.             }   
  43.         }   
  44.   
  45.         return false;   
  46.     }   
  47.     public String onPrepareStatement(String arg0) {   
  48.         // TODO Auto-generated method stub  
  49.         return arg0;   
  50.     }   
  51.                //保存时记录事件  
  52.     public boolean onSave(Object obj, Serializable arg1, Object[] arg2, String[] arg3, Type[] arg4) throws CallbackException {   
  53.         // TODO Auto-generated method stub  
  54.         String[] entitys EventRecord.getSaveEntitysFireEvent();   
  55.         for (String entityName entitys) {   
  56.             if (entityName.equals(obj.getClass().getSimpleName())) {   
  57.                 getEventRecordMethod(entityName, obj,EventRecord.getSaveInfo());   
  58.             }   
  59.         }   
  60.   
  61.         return false;   
  62.     }   
  63.                //根据反射机制执行事件记录类中相应的函数  
  64.     public void getEventRecordMethod(String entityName,Object obj,String info){   
  65.         try {   
  66.             Class[] parameterTypes {String.class,Class.forName(EventRecord.getPrefixPackageName()+entityName)};   
  67.             Method method EventRecord.class.getMethod(EventRecord.getPrefixMethodName()+entityName, parameterTypes);   
  68.             Object[] objs {info, Class.forName(EventRecord.getPrefixPackageName()+entityName).cast(obj)};   
  69.             method.invoke((EventRecord)ApplicationContextHolder.getBean("eventRecord"),objs);   
  70.         catch (Exception e) {   
  71. // TODO Auto-generated catch block   
  72.             e.printStackTrace();   
  73.         }   
  74.   
  75.  
package com.creawor.cbsms.util; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Iterator; import javacommon.util.ApplicationContextHolder; import org.hibernate.CallbackException; import org.hibernate.EntityMode; import org.hibernate.Interceptor; import org.hibernate.Transaction; import org.hibernate.type.Type; import com.creawor.cbsms.event.EventRecord; import com.creawor.cbsms.model.CbsChannel; import com.creawor.cbsms.model.CbsMessage; public class MyInterceptor implements Interceptor{ //删除时记录时间 public void onDelete(Object obj, Serializable arg1, Object[] arg2, String[] arg3, Type[] arg4) throws CallbackException { // TODO Auto-generated method stub String[] entitys = EventRecord.getDeleteEntitysFireEvent(); for (String entityName : entitys) { if (entityName.equals(obj.getClass().getSimpleName())) { getEventRecordMethod(entityName, obj,EventRecord.getDeleteInfo()); } } } //修改时记录事件 public boolean onFlushDirty(Object obj, Serializable id, Object[] currentState, Object[] previousState , String[] propertyNames, Type[] types){ String[] entitys = EventRecord.getUpdateEntitysFireEvent(); for (String entityName : entitys) { if (entityName.equals(obj.getClass().getSimpleName())) { getEventRecordMethod(entityName, obj, EventRecord.getUpdateInfo()); } } return false; } public String onPrepareStatement(String arg0) { // TODO Auto-generated method stub return arg0; } //保存时记录事件 public boolean onSave(Object obj, Serializable arg1, Object[] arg2, String[] arg3, Type[] arg4) throws CallbackException { // TODO Auto-generated method stub String[] entitys = EventRecord.getSaveEntitysFireEvent(); for (String entityName : entitys) { if (entityName.equals(obj.getClass().getSimpleName())) { getEventRecordMethod(entityName, obj,EventRecord.getSaveInfo()); } } return false; } //根据反射机制执行事件记录类中相应的函数 public void getEventRecordMethod(String entityName,Object obj,String info){ try { Class[] parameterTypes = {String.class,Class.forName(EventRecord.getPrefixPackageName()+entityName)}; Method method = EventRecord.class.getMethod(EventRecord.getPrefixMethodName()+entityName, parameterTypes); Object[] objs = {info, Class.forName(EventRecord.getPrefixPackageName()+entityName).cast(obj)}; method.invoke((EventRecord)ApplicationContextHolder.getBean("eventRecord"),objs); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }

 事件记录类:

Java代码 根据hibernate拦截器实现可配置日志的记录
  1. package com.creawor.cbsms.event;   
  2.   
  3. import java.sql.Timestamp;   
  4.   
  5. import javacommon.util.ApplicationContextHolder;   
  6.   
  7. import com.creawor.cbsms.dao.CbsEventDao;   
  8. import com.creawor.cbsms.model.CbsBsc;   
  9. import com.creawor.cbsms.model.CbsBscCells;   
  10. import com.creawor.cbsms.model.CbsChannel;   
  11. import com.creawor.cbsms.model.CbsEvent;   
  12. import com.creawor.cbsms.model.CbsUserRegister;   
  13. import com.creawor.cbsms.service.CbsEventManager;   
  14. import com.creawor.security.model.PermUser;   
  15.   
  16. public class EventRecord {   
  17.        
  18.                // 保存时要记录事件的对象  
  19.     private static String[] saveEntitysFireEvent "CbsBscCells",   
  20.                                                      "CbsChannel"   
  21.                                                      "CbsBsc" };   
  22.   
  23.     // 删除时要记录事件的对象   
  24.     private static String[] deleteEntitysFireEvent "CbsBscCells",   
  25.                                                        "CbsChannel",   
  26.                                                        "CbsBsc" };   
  27.   
  28.     // 更新时要记录事件的对象   
  29.     private static String[] updateEntitysFireEvent "CbsBscCells",   
  30.                                                        "CbsChannel"   
  31.                                                        "CbsBsc" };   
  32.   
  33.     // 包的前缀,反射得到类时使用   
  34.     private static String prefixPackageName "com.creawor.cbsms.model.";   
  35.        
  36.     // 记录该次操作的登录用户名:EventRecord为session范围  
  37.     private String userName;   
  38.   
  39.     // 调用函数的前缀,反射执行函数时使用   
  40.     private static String prefixMethodName "recordFor";   
  41.   
  42.     // 执行save时,事件描述   
  43.     private static String saveInfo "创建";   
  44.   
  45.     // 执行delete时,事件描述   
  46.     private static String deleteInfo "删除";   
  47.   
  48.     // 执行update时,事件描述   
  49.     private static String updateInfo "修改";   
  50.   
  51.        
  52.   
  53.     private CbsEventManager cbsEventManager;   
  54.   
  55.     // spring自动注入   
  56.     public void setCbsEventManager(CbsEventManager cbsEventManager) {   
  57.         this.cbsEventManager cbsEventManager;   
  58.     }   
  59.   
  60.       
  61.     public void recordForCbsChannel(String desc, CbsChannel channel) {   
  62.         StringBuffer eventDesc new StringBuffer(desc);   
  63.         eventDesc.append("频道" channel.getChannelName()).append("[").append(   
  64.                 channel.getChannelNum()).append("]");   
  65.         record(eventDesc.toString(), null);   
  66.     }   
  67.   
  68.       
  69.     public void recordForCbsBscCells(String desc, CbsBscCells cell) {   
  70.         StringBuffer eventDesc new StringBuffer(desc);   
  71.         eventDesc.append("小区"+cell.getCellName()).append("[").append(   
  72.                 cell.getCellId()).append("]");   
  73.         record(eventDesc.toString(), null);   
  74.     }   
  75.   
  76.       
  77.      public void record(String eventDesc, String eventOrigin) {   
  78.                              CbsEvent event new CbsEvent();   
  79.                              event.setEventDesc(userName   " eventDesc);   
  80.                              event.setEventOrigin(eventOrigin);   
  81.                              event.setStartTime(new Timestamp(System.currentTimeMillis()));   
  82.                             cbsEventManager.save(event);   
  83.                  }   
  84.        
  85.     public void setUserName(String userName) {   
  86.         this.userName userName;   
  87.     }   
  88.   
  89.     public static String[] getDeleteEntitysFireEvent() {   
  90.         return deleteEntitysFireEvent;   
  91.     }   
  92.   
  93.     public static String[] getSaveEntitysFireEvent() {   
  94.         return saveEntitysFireEvent;   
  95.     }   
  96.   
  97.     public static String[] getUpdateEntitysFireEvent() {   
  98.         return updateEntitysFireEvent;   
  99.     }   
  100.   
  101.     public static String getPrefixPackageName() {   
  102.         return prefixPackageName;   
  103.     }   
  104.   
  105.     public static void setPrefixPackageName(String prefixPackageName) {   
  106.         EventRecord.prefixPackageName prefixPackageName;   
  107.     }   
  108.   
  109.     public static String getPrefixMethodName() {   
  110.         return prefixMethodName;   
  111.     }   
  112.   
  113.     public static String getDeleteInfo() {   
  114.         return deleteInfo;   
  115.     }   
  116.   
  117.     public static String getSaveInfo() {   
  118.         return saveInfo;   
  119.     }   
  120.   
  121.     public static String getUpdateInfo() {   
  122.         return updateInfo;   
  123.     }   
  124.   
  125.  
package com.creawor.cbsms.event; import java.sql.Timestamp; import javacommon.util.ApplicationContextHolder; import com.creawor.cbsms.dao.CbsEventDao; import com.creawor.cbsms.model.CbsBsc; import com.creawor.cbsms.model.CbsBscCells; import com.creawor.cbsms.model.CbsChannel; import com.creawor.cbsms.model.CbsEvent; import com.creawor.cbsms.model.CbsUserRegister; import com.creawor.cbsms.service.CbsEventManager; import com.creawor.security.model.PermUser; public class EventRecord { // 保存时要记录事件的对象 private static String[] saveEntitysFireEvent = { "CbsBscCells", "CbsChannel", "CbsBsc" }; // 删除时要记录事件的对象 private static String[] deleteEntitysFireEvent = { "CbsBscCells", "CbsChannel", "CbsBsc" }; // 更新时要记录事件的对象 private static String[] updateEntitysFireEvent = { "CbsBscCells", "CbsChannel", "CbsBsc" }; // 包的前缀,反射得到类时使用 private static String prefixPackageName = "com.creawor.cbsms.model."; // 记录该次操作的登录用户名:EventRecord为session范围 private String userName; // 调用函数的前缀,反射执行函数时使用 private static String prefixMethodName = "recordFor"; // 执行save时,事件描述 private static String saveInfo = "创建"; // 执行delete时,事件描述 private static String deleteInfo = "删除"; // 执行update时,事件描述 private static String updateInfo = "修改"; private CbsEventManager cbsEventManager; // spring自动注入 public void setCbsEventManager(CbsEventManager cbsEventManager) { this.cbsEventManager = cbsEventManager; } public void recordForCbsChannel(String desc, CbsChannel channel) { StringBuffer eventDesc = new StringBuffer(desc); eventDesc.append("频道" + channel.getChannelName()).append("[").append( channel.getChannelNum()).append("]"); record(eventDesc.toString(), null); } public void recordForCbsBscCells(String desc, CbsBscCells cell) { StringBuffer eventDesc = new StringBuffer(desc); eventDesc.append("小区"+cell.getCellName()).append("[").append( cell.getCellId()).append("]"); record(eventDesc.toString(), null); }  public void record(String eventDesc, String eventOrigin) {     CbsEvent event = new CbsEvent();     event.setEventDesc(userName + "   " + eventDesc);    event.setEventOrigin(eventOrigin);    event.setStartTime(new Timestamp(System.currentTimeMillis()));    cbsEventManager.save(event);  } public void setUserName(String userName) { this.userName = userName; } public static String[] getDeleteEntitysFireEvent() { return deleteEntitysFireEvent; } public static String[] getSaveEntitysFireEvent() { return saveEntitysFireEvent; } public static String[] getUpdateEntitysFireEvent() { return updateEntitysFireEvent; } public static String getPrefixPackageName() { return prefixPackageName; } public static void setPrefixPackageName(String prefixPackageName) { EventRecord.prefixPackageName = prefixPackageName; } public static String getPrefixMethodName() { return prefixMethodName; } public static String getDeleteInfo() { return deleteInfo; } public static String getSaveInfo() { return saveInfo; } public static String getUpdateInfo() { return updateInfo; } }

 其中EventRecord 在spring中的配置为:

Java代码 根据hibernate拦截器实现可配置日志的记录
  1. <bean id="eventRecord" class="com.creawor.cbsms.event.EventRecord"  scope="session" autowire="byName"/>          
<bean id="eventRecord" class="com.creawor.cbsms.event.EventRecord" scope="session" />

 EventRecord 为session范围可以使字段userName记录每次登录人员的姓名

具体在每次登录后从spring容器中得到EventRecord然后set其userName即可!

最后一步要想让session范围生效还要在web.xml中添加配置:

Java代码 根据hibernate拦截器实现可配置日志的记录
  1. <web-app>   
  2.   ...   
  3.   <listener>   
  4.     <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>   
  5.   </listener>   
  6.   ...   
  7. </web-app>  
<web-app> ... <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> ... </web-app>

 这样如果想要记录一个业务bean增删改的操作只需在EventRecord中设置saveEntitysFireEvent,deleteEntitysFireEvent,updateEntitysFireEvent属性即可,同样也可使用配置文件配置,这样都可以使日志和事件的记录变得很简单!