Skip to content

Commit

Permalink
Added support for defining HandlerDefinitions and HandlerEnhancerDefi…
Browse files Browse the repository at this point in the history
…nitions using axon configuration and spring beans.
  • Loading branch information
m1l4n54v1c committed Apr 18, 2018
1 parent 83b2c1f commit 9ad4215
Show file tree
Hide file tree
Showing 44 changed files with 877 additions and 636 deletions.
Expand Up @@ -26,7 +26,6 @@
import org.axonframework.messaging.MessageHandler;
import org.axonframework.messaging.annotation.ClasspathParameterResolverFactory;
import org.axonframework.messaging.annotation.HandlerDefinition;
import org.axonframework.messaging.annotation.HandlerEnhancerDefinition;
import org.axonframework.messaging.annotation.MessageHandlingMember;
import org.axonframework.messaging.annotation.ParameterResolverFactory;

Expand Down Expand Up @@ -92,17 +91,26 @@ public AggregateAnnotationCommandHandler(Class<T> aggregateType, Repository<T> r
AnnotatedAggregateMetaModelFactory.inspectAggregate(aggregateType, parameterResolverFactory));
}

/**
* Initializes an AnnotationCommandHandler based on the annotations on given {@code aggregateType}, using the
* given {@code repository} to add and load aggregate instances, the given {@code parameterResolverFactory} and the
* given {@code handlerDefinition}.
*
* @param aggregateType The type of aggregate
* @param repository The repository providing access to aggregate instances
* @param commandTargetResolver The target resolution strategy
* @param parameterResolverFactory The strategy for resolving parameter values for handler methods
* @param handlerDefinition The handler definition used to create concrete handlers
*/
public AggregateAnnotationCommandHandler(Class<T> aggregateType, Repository<T> repository,
CommandTargetResolver commandTargetResolver,
Iterable<HandlerDefinition> handlerDefinitions,
Iterable<HandlerEnhancerDefinition> handlerEnhancerDefinitions,
ParameterResolverFactory parameterResolverFactory) {
ParameterResolverFactory parameterResolverFactory,
HandlerDefinition handlerDefinition) {
this(repository,
commandTargetResolver,
AnnotatedAggregateMetaModelFactory.inspectAggregate(aggregateType,
parameterResolverFactory,
handlerDefinitions,
handlerEnhancerDefinitions));
handlerDefinition));
}

/**
Expand Down
Expand Up @@ -21,9 +21,9 @@
import org.axonframework.common.Assert;
import org.axonframework.common.Registration;
import org.axonframework.messaging.MessageHandler;
import org.axonframework.messaging.annotation.ClasspathHandlerDefinition;
import org.axonframework.messaging.annotation.ClasspathParameterResolverFactory;
import org.axonframework.messaging.annotation.HandlerDefinition;
import org.axonframework.messaging.annotation.HandlerEnhancerDefinition;
import org.axonframework.messaging.annotation.ParameterResolverFactory;

import java.util.ArrayDeque;
Expand Down Expand Up @@ -60,27 +60,29 @@ public AnnotationCommandHandlerAdapter(Object annotatedCommandHandler) {
* @param annotatedCommandHandler The object containing the @CommandHandler annotated methods
* @param parameterResolverFactory The strategy for resolving handler method parameter values
*/
@SuppressWarnings("unchecked")
public AnnotationCommandHandlerAdapter(Object annotatedCommandHandler,
ParameterResolverFactory parameterResolverFactory) {
Assert.notNull(annotatedCommandHandler, () -> "annotatedCommandHandler may not be null");
this.modelInspector = AnnotatedAggregateMetaModelFactory.inspectAggregate((Class<Object>)annotatedCommandHandler.getClass(),
parameterResolverFactory);

this.target = annotatedCommandHandler;
this(annotatedCommandHandler,
parameterResolverFactory,
new ClasspathHandlerDefinition(Thread.currentThread().getContextClassLoader()));
}

/**
* Wraps the given {@code annotatedCommandHandler}, allowing it to be subscribed to a Command Bus.
*
* @param annotatedCommandHandler The object containing the @CommandHandler annotated methods
* @param parameterResolverFactory The strategy for resolving handler method parameter values
* @param handlerDefinition The handler definition used to create concrete handlers
*/
@SuppressWarnings("unchecked")
public AnnotationCommandHandlerAdapter(Object annotatedCommandHandler,
ParameterResolverFactory parameterResolverFactory,
Iterable<HandlerDefinition> handlerDefinitions,
Iterable<HandlerEnhancerDefinition> handlerEnhancerDefinitions) {
HandlerDefinition handlerDefinition) {
Assert.notNull(annotatedCommandHandler, () -> "annotatedCommandHandler may not be null");
this.modelInspector = AnnotatedAggregateMetaModelFactory
.inspectAggregate((Class<Object>) annotatedCommandHandler.getClass(),
parameterResolverFactory,
handlerDefinitions,
handlerEnhancerDefinitions);
handlerDefinition);

this.target = annotatedCommandHandler;
}
Expand Down
Expand Up @@ -30,7 +30,6 @@
import org.axonframework.eventsourcing.eventstore.DomainEventStream;
import org.axonframework.eventsourcing.eventstore.EventStore;
import org.axonframework.messaging.annotation.HandlerDefinition;
import org.axonframework.messaging.annotation.HandlerEnhancerDefinition;
import org.axonframework.messaging.annotation.ParameterResolverFactory;
import org.axonframework.messaging.unitofwork.CurrentUnitOfWork;
import org.slf4j.Logger;
Expand Down Expand Up @@ -126,18 +125,28 @@ public <T> Repository<T> createRepository(EventStore eventStore,
snapshotTriggerDefinition));
}

/**
* Create a repository instance for an aggregate created by the given {@code aggregateFactory}. The returning
* repository must be safe to use by this invoker instance.
*
* @param <T> The type of aggregate created by the factory
* @param eventStore The events store to load and publish events
* @param aggregateFactory The factory creating aggregate instances
* @param snapshotTriggerDefinition The trigger definition for snapshots
* @param parameterResolverFactory The factory used to resolve parameters on command handler methods
* @param handlerDefinition The handler definition used to create concrete handlers
* @return A Repository instance for the given aggregate
*/
@SuppressWarnings("unchecked")
public <T> Repository<T> createRepository(EventStore eventStore,
AggregateFactory<T> aggregateFactory,
SnapshotTriggerDefinition snapshotTriggerDefinition,
ParameterResolverFactory parameterResolverFactory,
Iterable<HandlerDefinition> handlerDefinitions,
Iterable<HandlerEnhancerDefinition> handlerEnhancerDefinitions) {
HandlerDefinition handlerDefinition) {
return repositories.computeIfAbsent(aggregateFactory.getAggregateType(),
k -> new DisruptorRepository<>(aggregateFactory, cache, eventStore,
parameterResolverFactory,
handlerDefinitions,
handlerEnhancerDefinitions,
handlerDefinition,
snapshotTriggerDefinition));
}

Expand Down Expand Up @@ -185,17 +194,15 @@ private DisruptorRepository(AggregateFactory<T> aggregateFactory, Cache cache, E

private DisruptorRepository(AggregateFactory<T> aggregateFactory, Cache cache, EventStore eventStore,
ParameterResolverFactory parameterResolverFactory,
Iterable<HandlerDefinition> handlerDefinitions,
Iterable<HandlerEnhancerDefinition> handlerEnhancerDefinitions,
HandlerDefinition handlerDefinition,
SnapshotTriggerDefinition snapshotTriggerDefinition) {
this.aggregateFactory = aggregateFactory;
this.cache = cache;
this.eventStore = eventStore;
this.snapshotTriggerDefinition = snapshotTriggerDefinition;
this.model = AnnotatedAggregateMetaModelFactory.inspectAggregate(aggregateFactory.getAggregateType(),
parameterResolverFactory,
handlerDefinitions,
handlerEnhancerDefinitions);
handlerDefinition);
}

@Override
Expand Down
Expand Up @@ -33,17 +33,16 @@
import org.axonframework.messaging.MessageDispatchInterceptor;
import org.axonframework.messaging.MessageHandler;
import org.axonframework.messaging.MessageHandlerInterceptor;
import org.axonframework.messaging.annotation.ClasspathHandlerDefinition;
import org.axonframework.messaging.annotation.ClasspathParameterResolverFactory;
import org.axonframework.messaging.annotation.HandlerDefinition;
import org.axonframework.messaging.annotation.HandlerEnhancerDefinition;
import org.axonframework.messaging.annotation.ParameterResolverFactory;
import org.axonframework.monitoring.MessageMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.concurrent.*;

import static java.lang.String.format;
Expand Down Expand Up @@ -405,16 +404,27 @@ public <T> Repository<T> createRepository(EventStore eventStore, AggregateFactor
parameterResolverFactory);
}

/**
* Creates a repository instance for an Event Sourced aggregate that is created by the given
* {@code aggregateFactory} and sourced from given {@code eventStore}. Parameters of the annotated methods are
* resolved using the given {@code parameterResolverFactory}.
*
* @param eventStore The Event Store to retrieve and persist events
* @param aggregateFactory The factory creating uninitialized instances of the Aggregate
* @param parameterResolverFactory The ParameterResolverFactory to resolve parameter values of annotated handler
* with
* @param handlerDefinition The handler definition used to create concrete handlers
* @param <T> The type of aggregate managed by this repository
* @return the repository that provides access to stored aggregates
*/
public <T> Repository<T> createRepository(EventStore eventStore, AggregateFactory<T> aggregateFactory,
ParameterResolverFactory parameterResolverFactory,
Iterable<HandlerDefinition> handlerDefinitions,
Iterable<HandlerEnhancerDefinition> handlerEnhancerDefinitions) {
HandlerDefinition handlerDefinition) {
return createRepository(eventStore,
aggregateFactory,
NoSnapshotTriggerDefinition.INSTANCE,
parameterResolverFactory,
handlerDefinitions,
handlerEnhancerDefinitions);
handlerDefinition);
}

/**
Expand Down Expand Up @@ -457,22 +467,33 @@ public <T> Repository<T> createRepository(EventStore eventStore, AggregateFactor
aggregateFactory,
snapshotTriggerDefinition,
parameterResolverFactory,
() -> ServiceLoader.load(HandlerDefinition.class).iterator(),
() -> ServiceLoader.load(HandlerEnhancerDefinition.class).iterator());
new ClasspathHandlerDefinition(getClass().getClassLoader()));
}

/**
* Creates a repository instance for an Event Sourced aggregate, sourced from given {@code eventStore}, that is
* created by the given {@code aggregateFactory}. Parameters of the annotated methods are resolved using the given
* {@code parameterResolverFactory}. The given {@code decorator} is used to intercept incoming streams of events
*
* @param eventStore The Event Store to retrieve and persist events
* @param aggregateFactory The factory creating uninitialized instances of the Aggregate
* @param snapshotTriggerDefinition The trigger definition for snapshots
* @param parameterResolverFactory The ParameterResolverFactory to resolve parameter values of annotated handler
* with
* @param handlerDefinition The handler definition used to create concrete handlers
* @param <T> The type of aggregate managed by this repository
* @return the repository that provides access to stored aggregates
*/
public <T> Repository<T> createRepository(EventStore eventStore, AggregateFactory<T> aggregateFactory,
SnapshotTriggerDefinition snapshotTriggerDefinition,
ParameterResolverFactory parameterResolverFactory,
Iterable<HandlerDefinition> handlerDefinitions,
Iterable<HandlerEnhancerDefinition> handlerEnhancerDefinitions) {
HandlerDefinition handlerDefinition) {
for (CommandHandlerInvoker invoker : commandHandlerInvokers) {
invoker.createRepository(eventStore,
aggregateFactory,
snapshotTriggerDefinition,
parameterResolverFactory,
handlerDefinitions,
handlerEnhancerDefinitions);
handlerDefinition);
}
return new DisruptorRepository<>(aggregateFactory.getAggregateType());
}
Expand Down
Expand Up @@ -20,7 +20,6 @@
import org.axonframework.commandhandling.model.inspection.AnnotatedAggregateMetaModelFactory;
import org.axonframework.common.Assert;
import org.axonframework.messaging.annotation.HandlerDefinition;
import org.axonframework.messaging.annotation.HandlerEnhancerDefinition;
import org.axonframework.messaging.annotation.ParameterResolverFactory;
import org.axonframework.messaging.unitofwork.CurrentUnitOfWork;
import org.axonframework.messaging.unitofwork.UnitOfWork;
Expand Down Expand Up @@ -70,15 +69,21 @@ protected AbstractRepository(Class<T> aggregateType, ParameterResolverFactory pa
nonNull(parameterResolverFactory, () -> "parameterResolverFactory may not be null")));
}

/**
* Initializes a repository that stores aggregate of the given {@code aggregateType}. All aggregates in this
* repository must be {@code instanceOf} this aggregate type.
*
* @param aggregateType The type of aggregate stored in this repository
* @param parameterResolverFactory The parameter resolver factory used to resolve parameters of annotated handlers
* @param handlerDefinition The handler definition used to create concrete handlers
*/
protected AbstractRepository(Class<T> aggregateType, ParameterResolverFactory parameterResolverFactory,
Iterable<HandlerDefinition> handlerDefinitions,
Iterable<HandlerEnhancerDefinition> handlerEnhancerDefinitions) {
HandlerDefinition handlerDefinition) {
this(AnnotatedAggregateMetaModelFactory
.inspectAggregate(nonNull(aggregateType, () -> "aggregateType may not be null"),
nonNull(parameterResolverFactory,
() -> "parameterResolverFactory may not be null"),
handlerDefinitions,
handlerEnhancerDefinitions));
nonNull(handlerDefinition, () -> "handler definition may not be null")));
}

/**
Expand Down

0 comments on commit 9ad4215

Please sign in to comment.