以hibernate.get(String, Serializable)方法为例:
get()的方法实现为:
图1:
public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException { LoadEvent event = new LoadEvent(id, entityName, lockMode, this); fireLoad(event, LoadEventListener.GET); return event.getResult(); } private void fireLoad(LoadEvent event, LoadType loadType) { errorIfClosed(); checkTransactionSynchStatus(); LoadEventListener[] loadEventListener = listeners.getLoadEventListeners(); for ( int i = 0; i < loadEventListener.length; i++ ) { loadEventListener[i].onLoad(event, loadType); } }
图2:
public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType) throws HibernateException { final SessionImplementor source = event.getSession(); EntityPersister persister; if ( event.getInstanceToLoad() != null ) { persister = source.getEntityPersister( null, event.getInstanceToLoad() ); //the load() which takes an entity does not pass an entityName event.setEntityClassName( event.getInstanceToLoad().getClass().getName() ); } else { persister = source.getFactory().getEntityPersister( event.getEntityClassName() ); } if ( persister == null ) { throw new HibernateException( "Unable to locate persister: " + event.getEntityClassName() ); } if ( persister.getIdentifierType().isComponentType() && EntityMode.DOM4J == event.getSession().getEntityMode() ) { // skip this check for composite-ids relating to dom4j entity-mode; // alternatively, we could add a check to make sure the incoming id value is // an instance of Element... } else { Class idClass = persister.getIdentifierType().getReturnedClass(); if ( idClass != null && ! idClass.isInstance( event.getEntityId() ) ) { throw new TypeMismatchException( "Provided id of the wrong type for class " + persister.getEntityName() + ". Expected: " + idClass + ", got " + event.getEntityId().getClass() ); } } EntityKey keyToLoad = new EntityKey( event.getEntityId(), persister, source.getEntityMode() ); try { if ( loadType.isNakedEntityReturned() ) { //do not return a proxy! //(this option indicates we are initializing a proxy) event.setResult( load(event, persister, keyToLoad, loadType) ); } else { //return a proxy if appropriate if ( event.getLockMode() == LockMode.NONE ) { event.setResult( proxyOrLoad(event, persister, keyToLoad, loadType) ); } else { event.setResult( lockAndLoad(event, persister, keyToLoad, loadType, source) ); } } } catch(HibernateException e) { log.info("Error performing load command", e); throw e; } }
如代码所示:当执行get()方法时,首先创建一个loadEvent,然后触发加载操作,获取对应listeners做出对应的响应;
SessionImpl为被观察者, listers为观察者, event为事件, event中包含了事件相关的属性。
ps:图1中为SessionImpl中的代码(SessionImpl为session的实现类), 图2为DefaultLoadEventListener的代码(DefaultLoadEventListener为LoadEventListener的实现类)