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