Class MoveSagaFieldToHandlerParameter
- All Implemented Interfaces:
Cloneable
Axon Framework 4 populated @Autowired or @Inject fields of a Saga instance through a
ResourceInjector, and called its @Autowired or @Inject setters. The legacy module resolves
Saga collaborators as handler method parameters instead, from the configuration or, with Spring, from the application
context, so an injected field stays null. Which fields move depends on the
type option:
- with a type, the private field of that type, injected directly or through a setter. Such a field that no method uses is removed;
- without a type, every private field an injection setter assigns, whatever its type, when a method uses it.
Its parameters are declared like the parameter of the setter, annotations such as
@Qualifierincluded. Such a field that no method uses stays, together with its setter, forMarkSagaResourceInjectionto mark.
- adds a parameter of the field's type, named after the field, to every
@SagaEventHandlerand@DeadlineHandlermethod that uses the field, directly or through private helper methods. With a type, a parameter of that type the method already declares is reused instead. A@DeadlineHandlerwithout parameters first gets aDeadlineMessageparameter: the collaborator resolves from the configuration, which ranks below the payload, so as the first parameter it would become the payload and the handler would stop matching its deadlines; - adds the same parameter to those private helper methods, and passes it along at their call sites;
- removes the field, together with its annotations and leading comments, once nothing refers to it;
- removes the
@Autowiredor@Injectsetter methods through which Axon Framework 4 injected the field, being injected methods that only assign their single parameter to it, as the legacy module does not call them either.
The migration is all-or-nothing per field. A use the recipe cannot move into a handler parameter leaves the field and
every one of its uses untouched, rather than producing a half-migrated Saga. Such a use is one in a constructor, a
static method, a non-private method that is not a handler (it may be called from outside the class), a field
initializer or initializer block, a nested, local or anonymous class, a method reference to an affected method or to
an injection setter, a call of an injection setter, an assignment to the field outside an injection setter, an access
through another instance, or a call of a @DeadlineHandler without parameters, which could not pass on its new
DeadlineMessage parameter. The same applies when the class declares more than one field of the configured
type. Without a type, a field also stays when a handler parameter would not receive what Axon Framework 4 passed its
setter: a setter with another annotation, such as @Qualifier or @Override, with an annotation
argument, such as required = false, overriding a supertype method, or with a @Value parameter.
Uses in other classes, such as subclasses, are not visible to the recipe, so only a field no other class can use is
moved: a private field, or in Kotlin, where properties are public by default, any property of a final class. A
Kotlin class is final unless declared open, abstract or sealed. A protected, package-private
or public field stays where it is. A field left in place is marked by MarkSagaResourceInjection when it, or
a setter assigning it, is injected; one that is not injected was never populated by Axon Framework 4 either, and
needs no marker.
Only Sagas are changed: classes annotated with the Spring @Saga stereotype or declaring a
@SagaEventHandler method. Other components, such as aggregates or Spring services, keep their fields, because
they are still injected there. Java and Kotlin sources are supported. The recipe is idempotent.
- Since:
- 5.4.0
- Author:
- Mateusz Nowak
-
Nested Class Summary
Nested classes/interfaces inherited from class org.openrewrite.Recipe
org.openrewrite.Recipe.Builder, org.openrewrite.Recipe.DelegatingRecipe -
Field Summary
Fields inherited from class org.openrewrite.Recipe
contributors, examples, PANIC -
Constructor Summary
ConstructorsConstructorDescriptionMoveSagaFieldToHandlerParameter(@Nullable String fullyQualifiedTypeName) Creates the recipe for Saga fields of the given type, or for the fields injection setters assign. -
Method Summary
Modifier and TypeMethodDescription@Nullable StringReturns the fully qualified name of the field type this recipe moves into handler parameters.org.openrewrite.TreeVisitor<?, org.openrewrite.ExecutionContext> Methods inherited from class org.openrewrite.Recipe
addDataTable, aggregateDataTableDescriptors, builder, buildRecipeList, causesAnotherCycle, clone, createRecipeDescriptor, equals, getContributors, getDataTableDescriptors, getDescriptor, getEstimatedEffortPerOccurrence, getExamples, getInstanceName, getInstanceNameSuffix, getJacksonPolymorphicTypeTag, getMaintainers, getName, getRecipeList, getTags, hashCode, maxCycles, noop, onComplete, run, run, run, setContributors, setExamples, validate, validate, validateAll, validateAll, withOptions
-
Constructor Details
-
MoveSagaFieldToHandlerParameter
Creates the recipe for Saga fields of the given type, or for the fields injection setters assign.- Parameters:
fullyQualifiedTypeName- the fully qualified name of the field type to move into handler parameters, ornullto move every field an injection setter assigns, whatever its type
-
-
Method Details
-
getFullyQualifiedTypeName
Returns the fully qualified name of the field type this recipe moves into handler parameters.- Returns:
- the fully qualified name of the field type, or
nullwhen the recipe moves every field an injection setter assigns
-
getDisplayName
- Specified by:
getDisplayNamein classorg.openrewrite.Recipe
-
getDescription
- Specified by:
getDescriptionin classorg.openrewrite.Recipe
-
getVisitor
public org.openrewrite.TreeVisitor<?,org.openrewrite.ExecutionContext> getVisitor()- Overrides:
getVisitorin classorg.openrewrite.Recipe
-