今天浏览博客,偶然浏览到了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的一个命令模式的操作过程.