learn and grow up

hibernate4监听器的实现简单解析

字数统计: 2k阅读时长: 9 min
2019/08/08 Share

这几天旧项目运维时发现曾经写的hibernate监听器很有意思,混合利用了工厂模式和观察者模式。所以特意记录一下

hibernate4的监听器注册方式不同于hibernate3在cfg.xml内进行注册的方式,而是新增了一个监听器注册类:org.hibernate.event.service.spi.EventListenerRegistry,注册方式为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Component
public class HandleEnvetListener {
//注册监听器

@Autowired
private SessionFactory sessionFactory;
@Autowired
private TestListener testListener;

@PostConstruct
public void registerListeners() {
EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(
EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.POST_COMMIT_UPDATE).appendListener(testListener);
}

}
  • 关于@PostConstruct,我们可以看下这个注解的官方解释:

    1
    2
    3
    4
    5
    @Target(value={METHOD})
    @Retention(value=RUNTIME)
    @Documented

    The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization. This method MUST be invoked before the class is put into service. This annotation MUST be supported on all classes that support dependency injection. The method annotated with PostConstruct MUST be invoked even if the class does not request any resources to be injected.

    这个注解是用来修饰方法,在jvm运行时保持有效的一个注解。该注解被用于bean初始化完和依赖注入完毕后、被其他bean使用之前必须被执行的方法,就算这个bean不被其他bean依赖,也会执行此方法。简单来说就是:这个注解修饰的方法会在bean内其他依赖注入完毕后执行。私以为类似于jquery的:

    1
    2
    3
    $(function() {
    init();
    });

接下来看看hibernate SessionFactory的核心:SessionFactory的实现类org.hibernate.internal.SessionFactoryImpl:

看这段代码前,我们先把关注点放到ServiceRegistry

ServiceRegistry 是 Service 的注册表, 它为Service提供了一个统一的加载 / 初始化 / 存放 / 获取机制.

把SessionFactoryImpl的构造器贴出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public SessionFactoryImpl(
final Configuration cfg,
Mapping mapping,
final ServiceRegistry serviceRegistry,
Settings settings,
SessionFactoryObserver observer) throws HibernateException {
LOG.debug( "Building session factory" );

sessionFactoryOptions = new SessionFactoryOptions() {
private EntityNotFoundDelegate entityNotFoundDelegate;

@Override
public StandardServiceRegistry getServiceRegistry() {
return (StandardServiceRegistry) serviceRegistry;
}

@Override
public Interceptor getInterceptor() {
return cfg.getInterceptor();
}

@Override
public EntityNotFoundDelegate getEntityNotFoundDelegate() {
if ( entityNotFoundDelegate == null ) {
if ( cfg.getEntityNotFoundDelegate() != null ) {
entityNotFoundDelegate = cfg.getEntityNotFoundDelegate();
}
else {
entityNotFoundDelegate = new EntityNotFoundDelegate() {
public void handleEntityNotFound(String entityName, Serializable id) {
throw new ObjectNotFoundException( id, entityName );
}
};
}
}
return entityNotFoundDelegate;
}
};

this.settings = settings;

this.properties = new Properties();
this.properties.putAll( cfg.getProperties() );

//获取总注册服务表,内部包含了各种默认的子服务注册
this.serviceRegistry = serviceRegistry.getService( SessionFactoryServiceRegistryFactory.class ).buildServiceRegistry(
this,
cfg
);
this.jdbcServices = this.serviceRegistry.getService( JdbcServices.class );
this.dialect = this.jdbcServices.getDialect();
this.cacheAccess = this.serviceRegistry.getService( CacheImplementor.class );
this.sqlFunctionRegistry = new SQLFunctionRegistry( getDialect(), cfg.getSqlFunctions() );
if ( observer != null ) {
this.observer.addObserver( observer );
}

this.typeResolver = cfg.getTypeResolver().scope( this );
this.typeHelper = new TypeLocatorImpl( typeResolver );

this.filters = new HashMap<String, FilterDefinition>();
this.filters.putAll( cfg.getFilterDefinitions() );

LOG.debugf( "Session factory constructed with filter configurations : %s", filters );
LOG.debugf( "Instantiating session factory with properties: %s", properties );


this.queryPlanCache = new QueryPlanCache( this );

// todo : everything above here consider implementing as standard SF service. specifically: stats, caches, types, function-reg

class IntegratorObserver implements SessionFactoryObserver {
private ArrayList<Integrator> integrators = new ArrayList<Integrator>();

@Override
public void sessionFactoryCreated(SessionFactory factory) {
}

@Override
public void sessionFactoryClosed(SessionFactory factory) {
for ( Integrator integrator : integrators ) {
integrator.disintegrate( SessionFactoryImpl.this, SessionFactoryImpl.this.serviceRegistry );
}
integrators.clear();
}
}

final IntegratorObserver integratorObserver = new IntegratorObserver();
this.observer.addObserver( integratorObserver );
for ( Integrator integrator : serviceRegistry.getService( IntegratorService.class ).getIntegrators() ) {
integrator.integrate( cfg, this, this.serviceRegistry );
integratorObserver.integrators.add( integrator );
}

//Generators:

........
}

我们重点看这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
this.serviceRegistry = serviceRegistry.getService( SessionFactoryServiceRegistryFactory.class ).buildServiceRegistry(
this,
cfg
);

.
.
.
//也就是先从参数serviceRegistry获取了SessionFactoryServiceRegistryFactory工厂,再利用工厂模式进行创建属于SessionFactoryImpl自己的ServiceRegistry,工厂具体创建方法如下:
//org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.SessionFactoryServiceRegistryImpl(ServiceRegistryImplementor, SessionFactoryImplementor, Configuration)
public SessionFactoryServiceRegistryImpl(
ServiceRegistryImplementor parent,
SessionFactoryImplementor sessionFactory,
Configuration configuration) {
super( parent );

this.sessionFactory = sessionFactory;
this.configuration = configuration;
this.metadata = null;

// for now, just use the standard initiator list
//可以看到这里就是对EventListenerRegistry初始化并注册
for ( SessionFactoryServiceInitiator initiator : StandardSessionFactoryServiceInitiators.LIST ) {
// create the bindings up front to help identify to which registry services belong
createServiceBinding( initiator );
}
}


//org.hibernate.service.internal.AbstractServiceRegistryImpl.createServiceBinding(ServiceInitiator<R>)
@SuppressWarnings({ "unchecked" })
protected <R extends Service> void createServiceBinding(ServiceInitiator<R> initiator) {
final ServiceBinding serviceBinding = new ServiceBinding( this, initiator );
serviceBindingMap.put( initiator.getServiceInitiated(), serviceBinding );
}
.
.
.
//StandardSessionFactoryServiceInitiators.LIST
//集合内包含了EventListenerServiceInitiator的注册启动器
public class StandardSessionFactoryServiceInitiators {
public static List<SessionFactoryServiceInitiator> LIST = buildStandardServiceInitiatorList();

private static List<SessionFactoryServiceInitiator> buildStandardServiceInitiatorList() {
final List<SessionFactoryServiceInitiator> serviceInitiators = new ArrayList<SessionFactoryServiceInitiator>();

serviceInitiators.add( EventListenerServiceInitiator.INSTANCE );
serviceInitiators.add( StatisticsInitiator.INSTANCE );
serviceInitiators.add( CacheInitiator.INSTANCE );

serviceInitiators.add( NativeQueryInterpreterInitiator.INSTANCE );

return Collections.unmodifiableList( serviceInitiators );
}

private StandardSessionFactoryServiceInitiators() {
}
}

//org.hibernate.event.service.internal.EventListenerServiceInitiator
public class EventListenerServiceInitiator implements SessionFactoryServiceInitiator<EventListenerRegistry> {
public static final EventListenerServiceInitiator INSTANCE = new EventListenerServiceInitiator();

@Override
public Class<EventListenerRegistry> getServiceInitiated() {
//也就是这里返回了EventListenerRegistry
return EventListenerRegistry.class;
}

@Override
public EventListenerRegistry initiateService(
SessionFactoryImplementor sessionFactory,
Configuration configuration,
ServiceRegistryImplementor registry) {
return new EventListenerRegistryImpl();
}

@Override
public EventListenerRegistry initiateService(
SessionFactoryImplementor sessionFactory,
MetadataImplementor metadata,
ServiceRegistryImplementor registry) {
return new EventListenerRegistryImpl();
}
}


//EventListenerRegistryImpl
public class EventListenerRegistryImpl implements EventListenerRegistry {
private Map<Class,Object> listenerClassToInstanceMap = new HashMap<Class, Object>();

//存放监听服务及其实现集合
private Map<EventType,EventListenerGroupImpl> registeredEventListenersMap = prepareListenerMap();
......
private static Map<EventType,EventListenerGroupImpl> prepareListenerMap() {
final Map<EventType,EventListenerGroupImpl> workMap = new HashMap<EventType, EventListenerGroupImpl>();

//初始化
// auto-flush listeners
prepareListeners(
AUTO_FLUSH,
new DefaultAutoFlushEventListener(),
workMap
);

// create listeners
prepareListeners(
PERSIST,
new DefaultPersistEventListener(),
workMap
);

// create-onflush listeners
prepareListeners(
.........

return Collections.unmodifiableMap( workMap );
}

private static <T> void prepareListeners(EventType<T> type, Map<EventType,EventListenerGroupImpl> map) {
prepareListeners( type, null, map );
}

private static <T> void prepareListeners(EventType<T> type, T defaultListener, Map<EventType,EventListenerGroupImpl> map) {
final EventListenerGroupImpl<T> listenerGroup;
if ( type == EventType.POST_COMMIT_DELETE
|| type == EventType.POST_COMMIT_INSERT
|| type == EventType.POST_COMMIT_UPDATE ) {
listenerGroup = new PostCommitEventListenerGroupImpl<T>( type );
}
else {
listenerGroup = new EventListenerGroupImpl<T>( type );
}

if ( defaultListener != null ) {
listenerGroup.appendListener( defaultListener );
}
//put
map.put( type, listenerGroup );
}
}

然后我们在上处获取了刚刚SessionFactory的EventListenerRegistry并将自己新建的监听类append进去,也就是append入:org.hibernate.event.service.internal.EventListenerRegistryImpl.registeredEventListenersMap内的某一个key.listeners内

众所周知,hibernate简单更新操作如下:

1
2
3
4
5
6
7
8
9
10
11
session = HibernateUtils.getSession();
session.beginTransaction();
Student student = new Student();
student.setName("张三");
student.setAge("21");
student.setId("23");
Serializable id_s = session.save(student);
System.out.println(id_s);
session.getTransaction().commit();
//spring事务拦截也是利用拦截器进行事务控制并通知监听器,见下图
//org.springframework.transaction.interceptor.TransactionInterceptor.invoke(MethodInvocation)---->org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(DefaultTransactionStatus)----->org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit()

spring对hibernate事务的支持

我们就以session.save(student)为例子来看看监听器如何运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//调用栈如下:
//org.hibernate.internal.SessionImpl.update(Object)---->org.hibernate.internal.SessionImpl.update(String, Object)-->org.hibernate.internal.SessionImpl.fireUpdate(SaveOrUpdateEvent)
private void fireUpdate(SaveOrUpdateEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
checkNoUnresolvedActionsBeforeOperation();
//获取当前有哪些监听器
for ( SaveOrUpdateEventListener listener : listeners( EventType.UPDATE ) ) {
//执行监听器的监听方法
listener.onSaveOrUpdate( event );
}
checkNoUnresolvedActionsAfterOperation();
}

//org.hibernate.internal.SessionImpl.listeners(EventType<T>)
private <T> Iterable<T> listeners(EventType<T> type) {
return eventListenerGroup( type ).listeners();
}

//重点!org.hibernate.internal.SessionImpl.eventListenerGroup(EventType<T>)
private <T> EventListenerGroup<T> eventListenerGroup(EventType<T> type) {
return factory.getServiceRegistry().getService( EventListenerRegistry.class ).getEventListenerGroup( type );
}

//可以清楚看到这里是获取了我们当时用到的ServiceRegistry,并读取到了监听注册类,再根据EventType读取我们当时append进去的监听类
//并执行监听器的接口实现方法
//hibernate4支持的监听方法实现方式都是如此~
//在这里可以看到有这么多事件:org.hibernate.event.spi.EventType<T>

总结下重要的类:

  • hibernate SessionFactory—-提供总服务注册表

    org.hibernate.SessionFactory:接口:session工厂

    org.hibernate.internal.SessionFactoryImpl:实现:session工厂

  • 总服务注册表serviceRegistry—为子服务注册提供注册到总session注册服务表上

    org.hibernate.internal.SessionFactoryImpl.serviceRegistry:接口:核心工厂内的服务注册表内部包含了N多种类的服务注册集合

    org.hibernate.service.internal.SessionFactoryServiceRegistryImpl:服务注册表实现类

    org.hibernate.service.internal.AbstractServiceRegistryImpl.serviceBindingMap:注册表内注册绑定的的map集合

    org.hibernate.service.internal.StandardSessionFactoryServiceInitiators:hibernate启动默认的service注册类集合

  • 子服务注册接口定义

    org.hibernate.service.spi.SessionFactoryServiceInitiator:接口:子服务注册接口统一定义类

  • 子服务注册:监听器注册类—为指定的监听服务提供注册

    org.hibernate.event.service.internal.EventListenerServiceInitiator:监听器service注册类构建类

    org.hibernate.event.service.spi.EventListenerRegistry:接口:监听器service注册服务类

    org.hibernate.event.service.internal.EventListenerRegistryImpl:实现:监听器service注册服务类

    org.hibernate.event.service.internal.EventListenerRegistryImpl.registeredEventListenersMap:监听器service注册提供实现类中的存放监听器种类-监听器实现类的集合对应关系的变量

    org.hibernate.event.service.internal.EventListenerGroupImpl:registeredEventListenersMap的value对象:监听器实现类的集合,包含了我们操作最终影响、后续业务调用的list:org.hibernate.event.service.internal.EventListenerGroupImpl.listeners

  • 监听器—最终注册进EventListenerRegistry

    org.hibernate.event.spi.EventType:规定了监听器种类和对应的监听器interface

    org.hibernate.event.spi.SaveOrUpdateEventListener:update的监听器接口。监听器需继承这个接口

CATALOG