Quick Start
This guickStart guide introduces how to apply domain events in aggregate root entity. not include command's single writer. Maven pom.xml <dependency> this quickStart's source code in github,
1. Create a Domain ModelDDD can help us find some domain models in business requirement, ar first let's begin with a domain model that represents a aggregate root entity. assume its name is MyModel: public class MyModel {
private String Id;
private String name;
....
}
when you begin to use jdonframework , you should make sure the domain object in-memory cache, there are two steps to reach the goal: (1) annotate your aggregate root with @Model @Model
public class MyModel {
private String Id;
private String name;
....
}
full code see MyModel.java
(2) annotate your factory/repository of the aggregate root with @Introduce(“modelCache”)
When a domain model object with @Model is fetch from repository, we need use @Introduce(“modelCache”) to mak the object live in memory. @Introduce(“modelCache”) must be annotated in the interfaces that @Model objects are created or reconstructed , the interfaces is such as repository class. DDD think repository is the transfering betwing the database data and domain object. This step is very important for domain events full code: RepositoryImp.java
2.create a Domain Eventdomain event is emitted from a domain model, generally is a aggregate root entity, jdonframework can help you develope domain event easily. at first, we create a domain event object, its name is MyModelDomainEvent, and this class is event producer, you can use jdonframework annotations to reache this goal. annotate a Producer class with @Introduce("message")
in this class, there are two methods with @Send("mytopic"); another is @Send("MyModel.findName"). they are all producer's emit methods @Introduce(“message”):"message" is the om.jdon.domain.message.MessageInterceptor configured in aspect.xml It means introducing a MessageInterceptor for this class. @ Send("mytopic"): "mytopic" is your topic name that equals to the "mytopic" in @Consumer("mytopic"); full code :MyModelDomainEvent.java
3. create a consumer for domain eventevery domain event has two parts: producer and consumer, annotate a class with @Consumer("mytopic"); or @OnEvent to make it is a consumer. in above step, MyModelDomainEvent.java have two topic/queue names: "MyModel.findName" and "saveMyModel", we must implement two consumers to listen/observe them. the first topic consumer class:
"FindNameListener" class must be labeled with @Consumer annotation, and implement a interface com.jdon.domain.message.DomainEventHandler, and then accomplish interface's method "onEvent". in this method you can acquire the domain Event(a value object, such as orderCreated ) that is emitted from producer "MyModelDomainEvent", here is FindNameEvent VO:
but maybe you wonder where the "FindNameEvent" instance comes from? in Procuder class, the method "asyncFindName" returns a type DomainMessage, and the code is "return new DomainMessage(findNameEvent)", yeah, the findNameEvent is input. in general, we should input a DomainEvents, such as "new OrderCreated(xx,xx)" , donot directly put entity instance.
another consumer annotation is @OnEvent, it can annotate any class with @Component:
the topic "saveMyModel" consumer is RepositoryImp, in this repository we just find the aggregate root "MyModel" instance, and we can save the model by "save(MyModelCreatedEvent myModelCreatedEvent)", here method parameter MyModelCreatedEvent is from the producer's method return's object(DomainMessage). myModelCreatedEvent as event object is too recommended, in general, we transfer a domainevent such as new OrderSaved(), if you saving the domain events, you can replay them to get root entity's state, this is called Event Soucing.
4. Introduce producer into domain objectnow we have a producer and two consumer, we need introduce the producer into our aggregate root entity(domain object):
@Inject is used to inject any class instance into domain model, here we inject our procuder MyModelDomainEvent. and in save() method, we invoke "myModelDomainEvent.save(new MyModelCreatedEvent(..))" to implement fire a domain event, such as new OrderSaved(); here, getName() method send a lazy-load event.
5. Clientall main steps finished. Service is a bounded context, and is a client for our aggregate:
Service's invoking :
above code is in SampleAppTest.java
this quickStart's source code in github getting-started-with-jdon blank project
|