对于日志和事件的记录在每个项目中都会用到,如果在每个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属性即可,同样也可使用配置文件配置,这样都可以使日志和事件的记录变得很简单!