/**
   * 根据聚合标识符和 指定 版本加载 聚合
   *
   * @param aggregateIdentifier the identifier of the aggregate to load
   * @param expectedVersion The expected version of the loaded aggregate
   * @return the fully initialized aggregate
   */
  @Override
  protected T doLoad(ID aggregateIdentifier, final Long expectedVersion) {
    AggregateEventStream events = null;
    AggregateEventStream originalStream = null;
    try {
      try {
        events = AggregateEventStore.readEvents(getTypeIdentifier(), aggregateIdentifier);
      } catch (EventStreamNotFoundException e) {
        throw new AggregateNotFoundException(aggregateIdentifier, "The aggregate was not found", e);
      }
      originalStream = events;
      for (EventStreamDecorator decorator : eventStreamDecorators) {
        events = decorator.decorateForRead(getTypeIdentifier(), aggregateIdentifier, events);
      }

      final T aggregate = aggregateFactory.createAggregate(aggregateIdentifier, events.peek());
      List<AggregateEvent> unseenEvents = new ArrayList<AggregateEvent>();
      aggregate.initializeState(new CapturingEventStream(events, unseenEvents, expectedVersion));
      if (aggregate.isDeleted()) {
        throw new AggregateDeletedException(aggregateIdentifier);
      }
      CurrentUnitOfWork.get()
          .registerListener(new ConflictResolvingListener(aggregate, unseenEvents));

      return aggregate;
    } finally {
      IOUtils.closeQuietlyIfCloseable(events);
      // if a decorator doesn't implement closeable, we still want to be sure we close the original
      // stream
      IOUtils.closeQuietlyIfCloseable(originalStream);
    }
  }
 /**
  * 执行真正的 保存 事件操作
  *
  * @param aggregate the aggregate to store
  */
 @Override
 protected void doSaveWithLock(T aggregate) {
   AggregateEventStream eventStream = aggregate.getUncommittedEvents();
   try {
     Iterator<EventStreamDecorator> iterator = eventStreamDecorators.descendingIterator();
     while (iterator.hasNext()) {
       eventStream =
           iterator.next().decorateForAppend(getTypeIdentifier(), aggregate, eventStream);
     }
     AggregateEventStore.appendEvents(getTypeIdentifier(), eventStream);
   } finally {
     IOUtils.closeQuietlyIfCloseable(eventStream);
   }
 }