项目中想记录操做日志,也就是针对一些关键的信息的操做,进行日志的记录。首先考虑到的就是在数据变动的时候能获得通知,而后去作变动信息的记录操做。项目中使用的hibernate4,因而上网查了一下,发如今hibernate支持interceptor和listener,可是interceptor是在操做前拦截。这个显然并不合适。操做前拦截的话,若是已经记录完了操做日志,结果数据操做并没成功怎么办?是否能回滚?总之感受不太合适。listener是满合适的。晚上不少的介绍,可是都是基于hibernate3之前版本的,都是说在spring配置sessionFactory的时候,加个eventListeners的属性就能够了。而hibernate4中已经彻底变了,spring对hibernate4也不支持eventListener属性了。网上搜来搜去,国人针对hibernate4这个改变的解决办法几乎没有。因而查看官方文档。发如今hibernate4中,listener的注册是经过Integrator来完成的,而Integrator是经过服务来发布的。须要在配置META-INF/services/org.hibernate.integrator.spi.Integrator文件中。可是这种方式,在listener中就没法使用spring的依赖注入,由于他们根本不在spring容器内。还好,sessionFactory中是能够得到到注册对象的。那么咱们只要再应用启动的时候,当spring环境准备好之后,在完成hibernate监听的注册就ok了。spring
个人实现方法是这样的:编写监听注册类:session
- public class ListenersImpl implements IListeners
- {
- private List<AlterationListener> listeners;
- private SessionFactory sessionFactory;
- private static final Logger logger = LoggerFactory.getLogger(ListenersImpl.class);
- public void setSessionFactory(SessionFactory sessionFactory)
- {
- this.sessionFactory = sessionFactory;
- }
- public void setListeners(List<AlterationListener> listeners)
- {
- this.listeners = listeners;
- }
- public void registerListeners()
- {
- EventListenerRegistry registry = ((SessionFactoryImpl)sessionFactory).getServiceRegistry().getService(EventListenerRegistry.class);
- for(AlterationListener listener : listeners)
- {
- registry.getEventListenerGroup(EventType.POST_INSERT).appendListener(listener);
- registry.getEventListenerGroup(EventType.POST_UPDATE).appendListener(listener);
- registry.getEventListenerGroup(EventType.POST_DELETE).appendListener(listener);
- logger.info("register hibernate listener : {} operation : [insert, update, delete]", listener.getClass().getName());
- }
- }
- }
在系统启动类中添加方法:app
- public static void startHibernateListeners()
- {
- if(applicationContext != null)
- {
- IListeners listeners = (IListeners)applicationContext.getBean("com.xk.commons.hibernate.listener.IListeners");
- listeners.registerListeners();
- }
- }
这个方法中用到了Spring容器applicationContext,也就是说,调用这个方法的时机必须在spring的环境准备好之后,以下:ide
- String springConfigPath = getSpringConfig();
- applicationContext = new FileSystemXmlApplicationContext(springConfigPath);
- logger.info("load spring config file : {}", springConfigPath);
- startHibernateListeners();
上面的代码片断很好理解。下面是咱们的监听的相应处理类:this
- public class AlterationListener implements PostUpdateEventListener, PostInsertEventListener, PostDeleteEventListener
- {
- /**
- *
- */
- private static final long serialVersionUID = 8775069565992961824L;
- private EventCenter eventCenter;
- public void setEventCenter(EventCenter eventCenter)
- {
- this.eventCenter = eventCenter;
- }
- private String eventType;
- public void setEventType(String eventType)
- {
- this.eventType = eventType;
- }
- public void onPostDelete(PostDeleteEvent event)
- {
- // TODO Auto-generated method stub
- }
- public void onPostInsert(PostInsertEvent event)
- {
- // TODO Auto-generated method stub
- }
- public void onPostUpdate(PostUpdateEvent event)
- {
- // TODO Auto-generated method stub
- Event evt = new Event(this, event, eventType);
- eventCenter.addEvent(evt);
- }
- }
能够看到在onPostUpdate方法中,咱们进行相应的变动处理就能够了。spa