hibernate 使用的设计模式(一) 观察者

  以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的实现类)

猜你喜欢

转载自abc08010051.iteye.com/blog/1956583
今日推荐