领域事件存储

通过AOP在所有应用服务方法前监听领域事件

package org.infinite.framework.ddd.event;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.infinite.framework.ddd.domain.model.DomainEvent;
import org.infinite.framework.ddd.domain.model.DomainEventPublisher;
import org.infinite.framework.ddd.domain.model.DomainEventSubscriber;
import org.springframework.beans.factory.annotation.Autowired;


/**
 *  存储所有的领域事件
 * 
 * @author Darkness
 * @date 2014-5-5 下午5:19:56 
 * @version V1.0
 */
@Aspect
public class DomainEventStoreProcessor {

    @Autowired
    private EventStore eventStore;

    /**
     * Registers a DomainEventStoreProcessor to listen
     * and forward all domain events to external subscribers.
     * This factory method is provided in the case where
     * Spring AOP wiring is not desired.
     */
    public static void register() {
        (new DomainEventStoreProcessor()).listen();
    }

    /**
     * Constructs my default state.
     */
    public DomainEventStoreProcessor() {
        super();
    }

    /**
     * Listens for all domain events and stores them.
     */
    @Before("execution(* org.infinite..application..*Service.*(..))")
    public void listen() {
        DomainEventPublisher
            .instance()
            .subscribe(new DomainEventSubscriber<DomainEvent>() {

                public void handleEvent(DomainEvent aDomainEvent) {
                    store(aDomainEvent);
                }

                public Class<DomainEvent> subscribedToEventType() {
                    return DomainEvent.class; // all domain events
                }
            });
    }

    /**
     * Stores aDomainEvent to the event store.
     * @param aDomainEvent the DomainEvent to store
     */
    private void store(DomainEvent aDomainEvent) {
        this.eventStore().append(aDomainEvent);
    }

    /**
     * Answers my EventStore.
     * @return EventStore
     */
    private EventStore eventStore() {
        return this.eventStore;
    }
}

事件仓储负责查询&持久化领域事件

package org.infinite.framework.ddd.event;

import java.util.List;

import org.infinite.framework.ddd.domain.model.DomainEvent;



/**
 *  事件存储器
 * 
 * @author Darkness
 * @date 2014-5-5 下午7:58:31 
 * @version V1.0
 */
public interface EventStore {

	List<StoredEvent> allStoredEventsBetween(long aLowStoredEventId, long aHighStoredEventId);

	List<StoredEvent> allStoredEventsSince(long aStoredEventId);

	StoredEvent append(DomainEvent aDomainEvent);

	void close();

	long countStoredEvents();
}

存储的事件定义

package org.infinite.framework.ddd.event;

import java.util.Date;

import org.infinite.framework.ddd.domain.model.DomainEvent;
import org.infinite.framework.utility.AssertionConcern;


/**
 *  存储的事件
 * 
 * @author Darkness
 * @date 2014-5-5 下午8:05:11 
 * @version V1.0
 */
public class StoredEvent extends AssertionConcern {

	private long eventId;// 序列号
    private Date occurredOn;
    private String typeName;// 领域事件的实际类名
    private String eventBody;// DomainEvent的序列化数据

    public StoredEvent(String aTypeName, Date anOccurredOn, String anEventBody) {
        this();

        this.setEventBody(anEventBody);
        this.setOccurredOn(anOccurredOn);
        this.setTypeName(aTypeName);
    }

    public StoredEvent(String aTypeName, Date anOccurredOn, String anEventBody, long anEventId) {
        this(aTypeName, anOccurredOn, anEventBody);

        this.setEventId(anEventId);
    }

    public String eventBody() {
        return this.eventBody;
    }

    public long eventId() {
        return this.eventId;
    }

    public Date occurredOn() {
        return this.occurredOn;
    }

    @SuppressWarnings("unchecked")
    public <T extends DomainEvent> T toDomainEvent() {
        Class<T> domainEventClass = null;

        try {
            domainEventClass = (Class<T>) Class.forName(this.typeName());
        } catch (Exception e) {
            throw new IllegalStateException("Class load error, because: " + e.getMessage());
        }

        T domainEvent =
            EventSerializer
                .instance()
                .deserialize(this.eventBody(), domainEventClass);

        return domainEvent;
    }

    public String typeName() {
        return this.typeName;
    }

    @Override
    public boolean equals(Object anObject) {
        boolean equalObjects = false;

        if (anObject != null && this.getClass() == anObject.getClass()) {
            StoredEvent typedObject = (StoredEvent) anObject;
            equalObjects = this.eventId() == typedObject.eventId();
        }

        return equalObjects;
    }

    @Override
    public int hashCode() {
        int hashCodeValue =
            + (1237 * 233)
            + (int) this.eventId();

        return hashCodeValue;
    }

    @Override
    public String toString() {
        return "StoredEvent [eventBody=" + eventBody + ", eventId=" + eventId + ", occurredOn=" + occurredOn + ", typeName="
                + typeName + "]";
    }

    public StoredEvent() {
        super();

        this.setEventId(-1);
    }

    protected void setEventBody(String anEventBody) {
        this.assertArgumentNotEmpty(anEventBody, "The event body is required.");
        this.assertArgumentLength(anEventBody, 1, 65000, "The event body must be 65000 characters or less.");

        this.eventBody = anEventBody;
    }

    protected void setEventId(long anEventId) {
        this.eventId = anEventId;
    }

    protected void setOccurredOn(Date anOccurredOn) {
        this.occurredOn = anOccurredOn;
    }

    protected void setTypeName(String aTypeName) {
        this.assertArgumentNotEmpty(aTypeName, "The event type name is required.");
        this.assertArgumentLength(aTypeName, 1, 100, "The event type name must be 100 characters or less.");

        this.typeName = aTypeName;
    }
}

事件序列化

package org.infinite.framework.ddd.event;

import org.infinite.framework.ddd.domain.model.DomainEvent;
import org.infinite.framework.ddd.serializer.AbstractSerializer;


/**
 *  事件序列化处理器
 * 
 * @author Darkness
 * @date 2014-5-5 下午8:08:48 
 * @version V1.0
 */
public class EventSerializer extends AbstractSerializer {

    private static EventSerializer eventSerializer;

    public static synchronized EventSerializer instance() {
        if (EventSerializer.eventSerializer == null) {
            EventSerializer.eventSerializer = new EventSerializer();
        }

        return EventSerializer.eventSerializer;
    }
 
    private EventSerializer() {
        this(false, false);
    }
 
    public EventSerializer(boolean isCompact) {
        this(false, isCompact);
    }

    public EventSerializer(boolean isPretty, boolean isCompact) {
        super(isPretty, isCompact);
    }

    /**
     *  序列化事件
     * 
     * @author Darkness
     * @date 2014-5-5 下午8:12:33 
     * @version V1.0
     */
    public String serialize(DomainEvent aDomainEvent) {
        String serialization = this.gson().toJson(aDomainEvent);

        return serialization;
    }

    /**
     *  反序列化事件
     * 
     * @author Darkness
     * @date 2014-5-5 下午8:13:23 
     * @version V1.0
     */
    public <T extends DomainEvent> T deserialize(String aSerialization, final Class<T> aType) {
        T domainEvent = this.gson().fromJson(aSerialization, aType);

        return domainEvent;
    }

}
package org.infinite.framework.ddd.serializer;

import java.lang.reflect.Type;
import java.util.Date;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

/**
 *  抽象序列化处理器
 * 
 * @author Darkness
 * @date 2014-5-5 下午8:09:47 
 * @version V1.0
 */
public class AbstractSerializer {

    private Gson gson;

    protected AbstractSerializer(boolean isCompact) {
        this(false, isCompact);
    }

    protected AbstractSerializer(boolean isPretty, boolean isCompact) {
        super();

        if (isPretty && isCompact) {
            this.buildForPrettyCompact();
        } else if (isCompact) {
            this.buildForCompact();
        } else {
            this.build();
        }
    }

    protected Gson gson() {
        return this.gson;
    }

    private void build() {
        this.gson = new GsonBuilder().registerTypeAdapter(Date.class, new DateSerializer())
                .registerTypeAdapter(Date.class, new DateDeserializer())
                .serializeNulls().create();
    }

    private void buildForCompact() {
        this.gson = new GsonBuilder().registerTypeAdapter(Date.class, new DateSerializer())
                .registerTypeAdapter(Date.class, new DateDeserializer())
                .create();
    }

    private void buildForPrettyCompact() {
        this.gson = new GsonBuilder().registerTypeAdapter(Date.class, new DateSerializer())
                .registerTypeAdapter(Date.class, new DateDeserializer())
                .setPrettyPrinting()
                .create();
    }

    private class DateSerializer implements JsonSerializer<Date> {
        public JsonElement serialize(Date source, Type typeOfSource, JsonSerializationContext context) {
            return new JsonPrimitive(Long.toString(source.getTime()));
        }
    }

    private class DateDeserializer implements JsonDeserializer<Date> {
        public Date deserialize(JsonElement json, Type typeOfTarget, JsonDeserializationContext context) throws JsonParseException {
            long time = Long.parseLong(json.getAsJsonPrimitive().getAsString());
            return new Date(time);
        }
    }
}

Hibernate事件仓储实现

package org.infinite.framework.ddd.port.adapter.persistence.hibernate;

import java.util.List;

import org.hibernate.Query;
import org.infinite.framework.ddd.domain.model.DomainEvent;
import org.infinite.framework.ddd.event.EventSerializer;
import org.infinite.framework.ddd.event.EventStore;
import org.infinite.framework.ddd.event.StoredEvent;
import org.infinite.framework.persistence.CleanableStore;
import org.infinite.framework.persistence.hibernate.HibernateSessionSupport;


/**
 * Hibernate事件存储器实现
 *  
 * @author Darkness
 * @date 2014-5-22 下午9:08:44
 * @version V1.0
 * @since ark 1.0
 */
public class HibernateEventStore
    extends HibernateSessionSupport
    implements EventStore, CleanableStore {

	public HibernateEventStore() {
        super();
    }

    /**
     * 查询存储的事件
     */
    @Override
    @SuppressWarnings("unchecked")
    public List<StoredEvent> allStoredEventsBetween(long aLowStoredEventId, long aHighStoredEventId) {
        Query query = this.session().createQuery(
                        "from StoredEvent as _obj_ "
                        + "where _obj_.eventId between ? and ? "
                        + "order by _obj_.eventId");

        query.setParameter(0, aLowStoredEventId);
        query.setParameter(1, aHighStoredEventId);

        List<StoredEvent> storedEvents = query.list();

        return storedEvents;
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<StoredEvent> allStoredEventsSince(long aStoredEventId) {
        Query query =
                this.session().createQuery(
                        "from StoredEvent as _obj_ "
                        + "where _obj_.eventId > ? "
                        + "order by _obj_.eventId");

        query.setParameter(0, aStoredEventId);

        List<StoredEvent> storedEvents = query.list();

        return storedEvents;
    }

    @Override
    public StoredEvent append(DomainEvent aDomainEvent) {
        String eventSerialization = EventSerializer.instance().serialize(aDomainEvent);

        StoredEvent storedEvent =
                new StoredEvent(
                        aDomainEvent.getClass().getName(),
                        aDomainEvent.occurredOn(),
                        eventSerialization);

        this.session().save(storedEvent);

        return storedEvent;
    }

    @Override
    public void close() {
        // no-op
    }

    @Override
    public long countStoredEvents() {
        Query query =
                this.session().createQuery("select count(*) from StoredEvent");

        long count = ((Long) query.uniqueResult()).longValue();

        return count;
    }

	@Override
	public void clean() {
		
	}
}


转载于:https://my.oschina.net/darkness/blog/359763

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值