spring3 hibernate4 如何支持EventListener

本文介绍如何在Spring+Hibernate4的环境下配置事件监听器。针对更新和保存操作,通过自定义监听器类并利用注解的方式实现特定业务逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为之前项目中用到的框架版本是spring3+hibernate3  在配置hibernate的监听事件的时候,一般是在applicationContext.xml中这样配置:

<!-- Hibernate配置 -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="namingStrategy">
			<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
				<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
				<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
				<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache/ehcache-hibernate-local.xml</prop>
				<prop key="hibernate.cache.use_query_cache">true</prop>
			</props>
		</property>
		<property name="packagesToScan" value="com.pengtu.entity" />
		<property name="eventListeners">
			<map>
				<entry key="save-update">
					<list>
						<bean class="com.pengtu.dao.hibernate.AuditListener" />
						<bean class="org.hibernate.event.def.DefaultSaveOrUpdateEventListener" />
					</list>
				</entry>
			</map>
		</property>
	</bean>
我们查看 org.springframework.orm.hibernate3.annotation. AnnotationSessionFactoryBean  的父类LocalSessionFactoryBean中 就有eventListeners属性的声明;

其中key-type的值有多种  具体如下:


因为系统要对新增和更新的数据做一部分共同的操作,比如:给每个新增的实体类添加创建时间、添加数据的时候将新增的信息输出到日志文件中等等。所以key-type选择了 save-update ,根据自己的需求来定义。

但是目前系统的hibernate换成了4.*版本,通过查看jar包下面的文件,发现4.*以后的版本都没有了对eventListeners的支持,如果还是按照上面的形式配置,会提示错误,

先贴上我当时配置时的代码 (还没有添加eventListeners):

 <!-- 配置hibernate session工厂 -->  
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" /> 
        <property name="hibernateProperties">  
            <props>  
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>  
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>  
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>  
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>  
                <prop key="hibernate.cache.use_query_cache">true</prop>
				<prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
				<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache/ehcache-hibernate-local.xml</prop>
				<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
            </props>  
        </property>  
        <!-- 自动扫描注解方式配置的hibernate类文件 -->  
        <property name="packagesToScan">  
            <list>     
                <value>com.pengtu.gsj.entity</value>  
            </list>  
        </property>  
    </bean> 
通过查看 org.springframework.orm.hibernate4. LocalSessionFactoryBean  源码,发现已经不支持EventListener了,但是肯定有新的方式来支持,通过查阅资料,发现4.*版本后都是通过注解的方式来配置,贴出具体的操作流程:

1.新增事件监听器: HibernateEventWiring:

package com.pengtu.gsj.dao.hibernate;

import java.util.Map;

import javax.annotation.PostConstruct;

import org.hibernate.SessionFactory;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.internal.SessionFactoryImpl;
import org.springframework.util.Assert;

/**
 * @author zl
 * @version 创建时间:2017年3月30日 上午11:02:33 类说明
 */
public class HibernateEventWiring {

	private SessionFactory sessionFactory;

	private Map<String, Object> listeners;

	@PostConstruct
	public void registerListeners() {
		Assert.notNull(sessionFactory);
		EventListenerRegistry eventListenerRegistry = ((SessionFactoryImpl) sessionFactory)
				.getServiceRegistry().getService(EventListenerRegistry.class);
		for (String key : listeners.keySet()) {
			EventType eventType = EventType.resolveEventTypeByName(key);
			eventListenerRegistry.getEventListenerGroup(eventType).appendListener(listeners.get(key));
		}
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public void setListeners(Map<String, Object> listeners) {
		this.listeners = listeners;
	}

}
  可能有些人对@Postconstruct  这里简单提一下:

 从Java EE5规范开始,Servlet增加了两个影响Servlet生命周期的注解(Annotation):@PostConstruct和@PreConstruct。这两个注解被用来修饰一个非静态的void()方法.而且这个方法不能有抛出异常声明。

使用方式,例如:

    @PostConstruct                                 //方式1
    public void someMethod(){
        ...
    }

    public @PostConstruct void someMethod(){        //方式2
        ...  
    }

@PostConstruct说明

  被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。

@PreConstruct说明

  被@PreConstruct修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreConstruct修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。

2.新增事件处理事件类:AccountSaveUpdateEventListener  方法中最好将key-type包含进去。

package com.pengtu.gsj.dao.hibernate;

import org.hibernate.HibernateException;
import org.hibernate.event.spi.SaveOrUpdateEvent;
import org.hibernate.event.spi.SaveOrUpdateEventListener;

/** 
 * @author zl 
 * @version 创建时间:2017年3月30日 上午11:16:47 
 * 类说明 
 */
public class AccountSaveUpdateEventListener implements SaveOrUpdateEventListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5890362089838366308L;

	@Override
	public void onSaveOrUpdate(SaveOrUpdateEvent event)
			throws HibernateException {
		System.out.println("测试在保存和更新操作之前的处理方法");
	}
 
	
}
注: 此处继承的接口根据自己的key-type来

3.在配置文件中配置监听:

 <bean class="com.pengtu.gsj.dao.hibernate.HibernateEventWiring">
    	<property name="sessionFactory"  ref="sessionFactory"></property>
    	<property name="listeners">
    		<map>
    			<entry key="save-update" value-ref="accountUpdateEventListener"></entry>
    		</map>
    	</property>
    </bean> 
    <bean id="accountUpdateEventListener" class="com.pengtu.gsj.dao.hibernate.AccountSaveUpdateEventListener" ></bean>

4.新增测试方法:

public class UserTest extends AbstractContextControllerTests{
	
	@Autowired
	private UserService userService;
	
	@Test
	public void setUser() throws Exception{
		 User user = new User();
		 user.setUsername("TM");
		 user.setPassword("1234");
		 user.setCreateDate(new Date());
		 user.setDelFlag("0");
		 userService.setUser(user);
	}	 	 	 
}
5.测试结果:



测试成功!

成功解决。。。

感谢大家的支持!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值