4.0版本改变了事件监听器注册的方式,以利用一些新增的功能,即服务和集成器。我不会过多地涉及服务,因为它们在其他地方已有说明。但让我们先从集成器的概念开始。
集成器合约
具体来说,我们谈论的是org.hibernate.integrator.spi.Integrator接口。org.hibernate.integrator.spi.Integrator的目的是提供一个简单的手段,允许开发者钩入构建功能SessionFactory的过程。Hibernate提供的一个标准服务是利用Java的java.util.ServiceLoader机制来发现org.hibernate.integrator.spi.Integrator实现。开发者只需定义一个名为/META-INF/services/org.hibernate.integrator.spi.Integrator的文件,并将其放在类路径上。本质上,这个文件的内容是一个或多个完全限定的org.hibernate.integrator.spi.Integrator实现类名,每个类名一行。有关此文件内容允许的语法的完整规范,请参阅java.util.ServiceLoader的Java文档。
org.hibernate.integrator.spi.Integrator接口定义了两个感兴趣的方法
public interface Integrator {
/**
* Perform integration.
*
* @param configuration The configuration used to create the session factory
* @param sessionFactory The session factory being created
* @param serviceRegistry The session factory's service registry
*/
public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry);
/**
* Tongue-in-cheek name for a shutdown callback.
*
* @param sessionFactory The session factory being closed.
* @param serviceRegistry That session factory's service registry
*/
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry);
/**
* Ignore this form! Just do nothing in impl. It uses the new metamodel api slated for completion in 5.0
*/
public void integrate(MetadataImplementor metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry );
}
integrate方法允许我们钩入构建过程;disintegrate允许我们钩入SessionFactory的关闭。
注册
Hibernate本身有几个org.hibernate.integrator.spi.Integrator接口的实现,它们执行事件监听器注册,可以参考。
- https://github.com/hibernate/hibernate-orm/blob/master/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversIntegrator.java
- https://github.com/hibernate/hibernate-orm/blob/master/hibernate-entitymanager/src/main/java/org/hibernate/ejb/event/JpaIntegrator.java
注册监听器的一般过程如下
public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
// As you might expect, an EventListenerRegistry is the place with which event listeners are registered It is a service
// so we look it up using the service registry
final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
// If you wish to have custom determination and handling of "duplicate" listeners, you would have to add an implementation
// of the org.hibernate.event.service.spi.DuplicationStrategy contract like this
eventListenerRegistry.addDuplicationStrategy( myDuplicationStrategy );
// EventListenerRegistry defines 3 ways to register listeners:
// 1) This form overrides any existing registrations with
eventListenerRegistry.setListeners( EventType.AUTO_FLUSH, myCompleteSetOfListeners );
// 2) This form adds the specified listener(s) to the beginning of the listener chain
eventListenerRegistry.prependListeners( EventType.AUTO_FLUSH, myListenersToBeCalledFirst );
// 3) This form adds the specified listener(s) to the end of the listener chain
eventListenerRegistry.appendListeners( EventType.AUTO_FLUSH, myListenersToBeCalledLast );
}