论坛首页 Java企业应用论坛

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

浏览 4070 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-01-05  

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

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

<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拦截器为:

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();
		}

}

 事件记录类:

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;
	}

	/**
	 * 存储频道修改的事件
	 * 
	 * @param desc
	 * @param channel
	 */
	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);
	}

	/**
	 * 存储小区修改的事件
	 * 
	 * @param desc
	 * @param cell
	 */
	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);
	}

	/**
	 * 存储**修改的事件
	 * 根据不同的对象拼接时间描述语句
	 * @param desc
	 * @param bsc
	 */
	 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中的配置为:

<bean id="eventRecord" class="com.creawor.cbsms.event.EventRecord"  scope="session" autowire="byName"/>	     

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

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

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

<web-app>
  ...
  <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  </listener>
  ...
</web-app>

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

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics