`
wu_quanyin
  • 浏览: 208144 次
  • 性别: Icon_minigender_1
  • 来自: 福建省
社区版块
存档分类
最新评论

监听者模式(Listener-Event)---hibernate

阅读更多

   今天浏览博客,偶然浏览到了hibernate中crud等,所采用的观察模式,追踪下源码,记录备忘.....

也可以看http://wuquanyin1011.iteye.com/admin/blogs/628993这篇文章(tomcat中容器周期的通知,也是采用了监听者的模式)

 

以session.save(object)为例

 

//追踪到这一步(SessionImpl下)
public void save(String entityName, Object object, Serializable id) throws HibernateException {
//这是创建一个事件,带有object(对像)
		fireSave( new SaveOrUpdateEvent(entityName, object, id, this) );
	}


private Serializable fireSave(SaveOrUpdateEvent event) {
		errorIfClosed();
		checkTransactionSynchStatus();
 //hibernate中提供了一系列的监听器,供调用
		SaveOrUpdateEventListener[] saveEventListener = listeners.getSaveEventListeners();
		for ( int i = 0; i < saveEventListener.length; i++ ) {
			saveEventListener[i].onSaveOrUpdate(event);//实行对象保存
		}
		return event.getResultId();
	}

 

 //从以上可以看出监听者模式的运用.

以下贴出所有的监听器

 

 

//需要操作的监听器都可以从这个类中获取
public class EventListeners extends Cloneable implements Serializable {

	private LoadEventListener[] loadEventListeners = { new DefaultLoadEventListener() };
	private SaveOrUpdateEventListener[] saveOrUpdateEventListeners = { new DefaultSaveOrUpdateEventListener() };
	private MergeEventListener[] mergeEventListeners = { new DefaultMergeEventListener() };
	private PersistEventListener[] persistEventListeners = { new DefaultPersistEventListener() };
	private PersistEventListener[] persistOnFlushEventListeners = { new DefaultPersistOnFlushEventListener() };
	private ReplicateEventListener[] replicateEventListeners = { new DefaultReplicateEventListener() };
	private DeleteEventListener[] deleteEventListeners = { new DefaultDeleteEventListener() };
	private AutoFlushEventListener[] autoFlushEventListeners = { new DefaultAutoFlushEventListener() };
	private DirtyCheckEventListener[] dirtyCheckEventListeners = { new DefaultDirtyCheckEventListener() };
	private FlushEventListener[] flushEventListeners = { new DefaultFlushEventListener() };
	private EvictEventListener[] evictEventListeners = { new DefaultEvictEventListener() };
	private LockEventListener[] lockEventListeners = { new DefaultLockEventListener() };
	private RefreshEventListener[] refreshEventListeners = { new DefaultRefreshEventListener() };
	private FlushEntityEventListener[] flushEntityEventListeners = { new DefaultFlushEntityEventListener() };
	private InitializeCollectionEventListener[] initializeCollectionEventListeners = 
			{ new DefaultInitializeCollectionEventListener() };

	private PostLoadEventListener[] postLoadEventListeners = { new DefaultPostLoadEventListener() };
	private PreLoadEventListener[] preLoadEventListeners = { new DefaultPreLoadEventListener() };
	
	private PreDeleteEventListener[] preDeleteEventListeners = {};
	private PreUpdateEventListener[] preUpdateEventListeners = {};
	private PreInsertEventListener[] preInsertEventListeners = {};
	private PostDeleteEventListener[] postDeleteEventListeners = {};
	private PostUpdateEventListener[] postUpdateEventListeners = {};
	private PostInsertEventListener[] postInsertEventListeners = {};
	private PostDeleteEventListener[] postCommitDeleteEventListeners = {};
	private PostUpdateEventListener[] postCommitUpdateEventListeners = {};
	private PostInsertEventListener[] postCommitInsertEventListeners = {};

	private SaveOrUpdateEventListener[] saveEventListeners = { new DefaultSaveEventListener() };
	private SaveOrUpdateEventListener[] updateEventListeners = { new DefaultUpdateEventListener() };
	private MergeEventListener[] saveOrUpdateCopyEventListeners = { new DefaultSaveOrUpdateCopyEventListener() };//saveOrUpdateCopy() is deprecated!

	private static Map eventInterfaceFromType;

	static {
		eventInterfaceFromType = new HashMap();

		eventInterfaceFromType.put("auto-flush", AutoFlushEventListener.class);
		eventInterfaceFromType.put("merge", MergeEventListener.class);
		eventInterfaceFromType.put("create", PersistEventListener.class);
		eventInterfaceFromType.put("create-onflush", PersistEventListener.class);
		eventInterfaceFromType.put("delete", DeleteEventListener.class);
		eventInterfaceFromType.put("dirty-check", DirtyCheckEventListener.class);
		eventInterfaceFromType.put("evict", EvictEventListener.class);
		eventInterfaceFromType.put("flush", FlushEventListener.class);
		eventInterfaceFromType.put("flush-entity", FlushEntityEventListener.class);
		eventInterfaceFromType.put("load", LoadEventListener.class);
		eventInterfaceFromType.put("load-collection", InitializeCollectionEventListener.class);
		eventInterfaceFromType.put("lock", LockEventListener.class);
		eventInterfaceFromType.put("refresh", RefreshEventListener.class);
		eventInterfaceFromType.put("replicate", ReplicateEventListener.class);
		eventInterfaceFromType.put("save-update", SaveOrUpdateEventListener.class);
		eventInterfaceFromType.put("save", SaveOrUpdateEventListener.class);
		eventInterfaceFromType.put("update", SaveOrUpdateEventListener.class);
		eventInterfaceFromType.put("pre-load", PreLoadEventListener.class);
		eventInterfaceFromType.put("pre-update", PreUpdateEventListener.class);
		eventInterfaceFromType.put("pre-delete", PreDeleteEventListener.class);
		eventInterfaceFromType.put("pre-insert", PreInsertEventListener.class);
		eventInterfaceFromType.put("post-load", PostLoadEventListener.class);
		eventInterfaceFromType.put("post-update", PostUpdateEventListener.class);
		eventInterfaceFromType.put("post-delete", PostDeleteEventListener.class);
		eventInterfaceFromType.put("post-insert", PostInsertEventListener.class);
		eventInterfaceFromType.put("post-commit-update", PostUpdateEventListener.class);
		eventInterfaceFromType.put("post-commit-delete", PostDeleteEventListener.class);
		eventInterfaceFromType.put("post-commit-insert", PostInsertEventListener.class);
		eventInterfaceFromType = Collections.unmodifiableMap( eventInterfaceFromType );
	}
//....略
}

 

 事件的生成...

hibernate中抽取了AbstractEvent的抽象类,如下

 

public abstract class AbstractEvent implements Serializable {

      //存放SessionImpl,该类实现了以下的接口
	private final EventSource session;

    /**
     * Constructs an event from the given event session.
     *
     * @param source The session event source.
     */
	public AbstractEvent(EventSource source) {
		this.session = source;
	}

    /**
     * Returns the session event source for this event.  This is the underlying
     * session from which this event was generated.
     *
     * @return The session event source.
     */
	public final EventSource getSession() {
		return session;
	}

}

 

  SaveEvent,hibernate就是根据以下的模式抽象出一系列的操作(LoadEvent等)

 

//进行一些参数赋值
public class SaveOrUpdateEvent extends AbstractEvent {

	private Object object;
	private Serializable requestedId;
	private String entityName;
	private Object entity;
	private EntityEntry entry;
	private Serializable resultId;

	public SaveOrUpdateEvent(String entityName, Object original, EventSource source) {
		this(original, source);
		this.entityName = entityName;
	}

	public SaveOrUpdateEvent(String entityName, Object original, Serializable id, EventSource source) {
		this(entityName, original, source);
		this.requestedId = id;
		if ( requestedId == null ) {
			throw new IllegalArgumentException(
					"attempt to create saveOrUpdate event with null identifier"
				);
		}
	}

	public SaveOrUpdateEvent(Object object, EventSource source) {
		super(source);
		if ( object == null ) {
			throw new IllegalArgumentException(
					"attempt to create saveOrUpdate event with null entity"
				);
		}
		this.object = object;
	}

	public Object getObject() {
		return object;
	}

	public void setObject(Object object) {
		this.object = object;
	}

	public Serializable getRequestedId() {
		return requestedId;
	}

	public void setRequestedId(Serializable requestedId) {
		this.requestedId = requestedId;
	}

	public String getEntityName() {
		return entityName;
	}

	public void setEntityName(String entityName) {
		this.entityName = entityName;
	}

	public Object getEntity() {
		return entity;
	}
	
	public void setEntity(Object entity) {
		this.entity = entity;
	}
	
	public EntityEntry getEntry() {
		return entry;
	}
	
	public void setEntry(EntityEntry entry) {
		this.entry = entry;
	}

	public Serializable getResultId() {
		return resultId;
	}

	public void setResultId(Serializable resultId) {
		this.resultId = resultId;
	}
}
 

 现在查看下,hibernate是如何利用Listener对Event进行操作

 

这一步的操作如下.

 

 

saveEventListener[i].onSaveOrUpdate(event);//实行对象保存

 

 

public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener implements SaveOrUpdateEventListener {

	private static final Log log = LogFactory.getLog(DefaultSaveOrUpdateEventListener.class);

	/** 
	 * Handle the given update event.
	 *
	 * @param event The update event to be handled.
	 * @throws HibernateException
	 */
     //进行对象的保存操作
	public void onSaveOrUpdate(SaveOrUpdateEvent event) throws HibernateException {
		
		final SessionImplementor source = event.getSession();
		final Object object = event.getObject();

		final Serializable requestedId = event.getRequestedId();
		if ( requestedId!=null ) {
			//assign the requested id to the proxy, *before* 
			//reassociating the proxy
			if ( object instanceof HibernateProxy ) {
				( (HibernateProxy) object ).getHibernateLazyInitializer().setIdentifier(requestedId);
			}
		}
		
		if ( reassociateIfUninitializedProxy(object, source) ) {
			log.trace("reassociated uninitialized proxy");
			// an uninitialized proxy, noop, don't even need to 
			// return an id, since it is never a save()
		}
		else {
			//initialize properties of the event:
			final Object entity = source.getPersistenceContext().unproxyAndReassociate(object);
			event.setEntity(entity);
			event.setEntry( source.getPersistenceContext().getEntry(entity) );
			//return the id in the event object
			event.setResultId( performSaveOrUpdate(event) );
		}
		
	}
//...略
}

以上为hibernate的一个命令模式的操作过程.

 

 

 

分享到:
评论
4 楼 spawnyy 2011-03-15  
我认为观察者模式+命令模式的一种变体,因为事件监听模式是J2EE设计模式中模式之一。
3 楼 Caedmon 2011-03-03  
监听模式就是观察者模式吧
2 楼 weilingfeng98 2011-01-12  
到底是command 还是观察者模式
1 楼 wgx198302 2010-05-24  
正在学习command模式

相关推荐

    listener-tnsname

    listener-tnsnamelistener-tnsnamelistener-tnsnamelistener-tnsnamelistener-tnsnamelistener-tnsnamelistener-tnsnamelistener-tnsname

    kktix-event-listener

    $ npm install kktix-event-listener 用法 var kktixEventListener = require ( 'kktix-event-listener' ) ; kktixEventListener ( 'http://reactjs.kktix.cc/events/react9' ) ; //=&gt; 命令行界面 $ npm install -g ...

    debug-event-listener.rar_The Listener

    "debug-event-listener.rar_The Listener"这一主题关注的是如何利用Debug对象及其监听器功能来优化和理解代码执行的过程。在这个压缩包中,我们有两个核心文件:10.1.4-4.js和debug-event-listener.js,它们可能包含...

    making-sense-dependency-injection-test-execution-listener-源码.rar

    本文将通过分析"making-sense-dependency-injection-test-execution-listener-源码"来深入探讨这两个概念。 1. 依赖注入(Dependency Injection) 依赖注入的核心思想是,对象不应该自行创建或查找它所依赖的对象...

    Listener-client.rar_TCP sql_c# TCP_listener_tcp listener_聊天 sql

    本文将深入探讨“Listener-client.rar”这个压缩包中涉及的TCP/IP通信、SQL交互以及C#编程技术,如何在客户端与服务器之间建立稳定的聊天功能。 首先,TCP(Transmission Control Protocol)是一种面向连接的、可靠...

    IE8-EventListener:IE8的Polyfill

    IE8-EventListener IE8的Polyfill 我怎么才能得到它? IE8-EventListener可通过npm获得,并可以使用以下命令进行安装: npm install ie8-eventlistener 它是什么? IE8-EventListener努力向IE8添加完全的...

    supervisor-event-listener:Supervisor事件通知, 支持邮件, Slack, WebHook

    supervisor-event-listener Supervisor事件通知, 支持邮件, Slack, WebHook 简介 Supervisor是*nix环境下的进程管理工具, 可以把前台进程转换为守护进程, 当进程异常退出时自动重启. supervisor-event-listener监听...

    jmeter-datadog-backend-listener-0.3.1.zip

    "jmeter-datadog-backend-listener-0.3.1.zip"这个压缩包就是为实现JMeter与DataDog集成提供的插件,让我们一起深入了解这个插件的功能和使用方法。 首先,"lib"目录中的文件是该插件的核心组成部分,它们包含了...

    tc-init-health-check-listener-7.0.52.zip

    【tc-init-health-check-listener-7.0.52.zip】是一个开源项目,主要关注的是对Tomcat服务器的健康检查和初始化监听器。这个项目旨在提供一种方式来监控和管理Tomcat服务器的生命周期,确保其在运行过程中能够稳定、...

    spring-listener-0.0.1-SNAPSHOT.jar

    spring内置监听者demo

    openstack-barbican-keystone-listener-9.0.0-1.el8.noarch.rpm

    官方离线安装包,亲测可用

    tetra-listener-vagrant:TETRA-Listener流浪者模板

    tetra-listener-vagrant是一个基于Vagrant的项目模板,专门设计用于TETRA-Listener,一个可能用于无线电通信监听或分析的软件工具。这个模板简化了TETRA-Listener的部署过程,使得开发者和IT专业人员能够快速设置一...

    spring和hibernate整合

    在web.Xml中&lt;context-param&gt; &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt; ... &lt;listener-class&gt;org.springframework.web.context.request.RequestContextListener&lt;/listener-class&gt; &lt;/listener&gt;

    mobx-event-bus:基于Mobx的超小型事件总线,允许组件之间进行发布-订阅式通信

    mobx-event-bus· Tiny库允许组件之间进行发布-订阅式通信,而无需组件之间进行显式注册。 安装 npm install mobx-event-bus --save 用法 基本的 import { eventBus , subscribe } from 'mobx-event-bus' class ...

    3.4-return-listener-消息处理机制1

    本文将深入探讨Return Listener的工作原理、使用场景以及如何在生产者和消费者端实现。 **Return Listener机制** 1. **消息路由流程** - **生产者**:发送消息到Exchange(交换机),指定一个Routing Key。 - **...

    23-Listener-源代码.rar

    案例-使用监听器完成定时生日祝福、,一、监听器Listener 二、邮箱服务器。 1.什么是监听器? 2.监听器有哪些? 3.监听三大域对象的创建与销毁的监听器 4.监听三大域对象的属性变化的 5.与session中的绑定的...

    use-typed-event-listener:支持TypeScript的React Hook for DOM事件监听器

    use-typed-event-listener是支持TypeScript的DOM事件侦听器的React Hook 借助TypeScript的帮助,此程序包可以检测元素支持的事件类型,并自动为事件强制转换正确的类型 安装 npm install use-typed-event-listener...

    PyPI 官网下载 | ndarray_listener-1.0.27.tar.gz

    在Python中,我们可以使用`tarfile`和`gzip`模块来分别处理这两种格式,从而解压`ndarray_listener-1.0.27.tar.gz`。 在安装这个库时,通常会使用`pip`,Python的包管理器。用户可以通过以下命令来安装: ```bash ...

    openstack-aodh-listener-6.0.1-1.el7.noarch.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

    boot-example-event-2.0.5

    `boot-example-event-2.0.5`项目提供了关于如何自定义并使用Spring Boot事件监听器的实例。让我们深入探讨这个话题。 首先,Spring框架有一个核心概念叫做ApplicationEvent,它是所有自定义事件的基类。当你在应用...

Global site tag (gtag.js) - Google Analytics