1616
1717package org .axonframework .springboot .aot ;
1818
19+ import org .axonframework .common .Priority ;
20+ import org .axonframework .common .ReflectionUtils ;
21+ import org .axonframework .common .annotation .AnnotationUtils ;
1922import org .axonframework .messaging .Message ;
2023import org .axonframework .messaging .annotation .AnnotatedHandlerInspector ;
24+ import org .axonframework .messaging .annotation .ClasspathParameterResolverFactory ;
2125import org .axonframework .messaging .annotation .MessageHandlingMember ;
26+ import org .axonframework .messaging .annotation .MultiParameterResolverFactory ;
27+ import org .axonframework .messaging .annotation .ParameterResolver ;
28+ import org .axonframework .messaging .annotation .ParameterResolverFactory ;
29+ import org .axonframework .modelling .command .AggregateMember ;
2230import org .axonframework .queryhandling .annotation .QueryHandlingMember ;
2331import org .axonframework .spring .config .MessageHandlerLookup ;
2432import org .springframework .aot .generate .GenerationContext ;
3139import org .springframework .beans .factory .config .ConfigurableListableBeanFactory ;
3240
3341import java .lang .reflect .Constructor ;
42+ import java .lang .reflect .Executable ;
3443import java .lang .reflect .Method ;
44+ import java .lang .reflect .Parameter ;
3545import java .util .Collection ;
46+ import java .util .HashSet ;
3647import java .util .List ;
48+ import java .util .Map ;
49+ import java .util .Optional ;
50+ import java .util .Set ;
3751import java .util .stream .Collectors ;
52+ import java .util .stream .Stream ;
3853
3954/**
4055 * BeanFactoryInitializationAotProcessor that registers message handler methods declared on beans for reflection. This
@@ -50,19 +65,59 @@ public class MessageHandlerRuntimeHintsRegistrar implements BeanFactoryInitializ
5065
5166 @ Override
5267 public BeanFactoryInitializationAotContribution processAheadOfTime (ConfigurableListableBeanFactory beanFactory ) {
53- List <Class <?>> messageHandlingClasses =
68+ Set <Class <?>> messageHandlingClasses =
5469 MessageHandlerLookup .messageHandlerBeans (messageType (), beanFactory , true )
5570 .stream ()
5671 .map (beanFactory ::getType )
57- .distinct ()
58- .collect (Collectors .toList ());
59- List <MessageHandlingMember <?>> messageHandlingMembers = messageHandlingClasses
72+ .collect (Collectors .toSet ());
73+
74+ Set <Class <?>> detectedClasses = new HashSet <>();
75+ messageHandlingClasses .forEach (c -> registerAggregateMembers (c , detectedClasses ));
76+
77+ List <MessageHandlingMember <?>> messageHandlingMembers = detectedClasses
6078 .stream ()
61- .flatMap (beanType -> AnnotatedHandlerInspector .inspectType (beanType ).getAllHandlers ().values ()
62- .stream ())
79+ .flatMap (beanType ->
80+ {
81+ AnnotatedHandlerInspector <?> inspector = AnnotatedHandlerInspector .inspectType (
82+ beanType ,
83+ MultiParameterResolverFactory .ordered (
84+ ClasspathParameterResolverFactory .forClass (beanType ),
85+ new LenientParameterResolver ()
86+ ));
87+ return Stream .concat (inspector .getAllHandlers ().values ().stream (),
88+ inspector .getAllInterceptors ().values ().stream ());
89+ })
6390 .flatMap (Collection ::stream )
6491 .collect (Collectors .toList ());
65- return new MessageHandlerContribution (messageHandlingClasses , messageHandlingMembers );
92+ return new MessageHandlerContribution (detectedClasses , messageHandlingMembers );
93+ }
94+
95+ private void registerAggregateMembers (Class <?> entityType , Set <Class <?>> reflectiveClasses ) {
96+ if (!reflectiveClasses .add (entityType )) {
97+ return ;
98+ }
99+
100+ ReflectionUtils .fieldsOf (entityType ).forEach (field -> {
101+ Optional <Map <String , Object >> annotationAttributes = AnnotationUtils .findAnnotationAttributes (field ,
102+ AggregateMember .class );
103+ if (annotationAttributes .isPresent ()) {
104+ Class <?> declaredType = (Class <?>) annotationAttributes .get ().get ("type" );
105+ Class <?> forwardingMode = (Class <?>) annotationAttributes .get ().get ("eventForwardingMode" );
106+ reflectiveClasses .add (forwardingMode );
107+
108+ if (declaredType != Void .class ) {
109+ registerAggregateMembers (declaredType , reflectiveClasses );
110+ } else if (Map .class .isAssignableFrom (field .getType ())) {
111+ Optional <Class <?>> type = ReflectionUtils .resolveMemberGenericType (field , 1 );
112+ type .ifPresent (t -> registerAggregateMembers (t , reflectiveClasses ));
113+ } else if (Collection .class .isAssignableFrom (field .getType ())) {
114+ Optional <Class <?>> type = ReflectionUtils .resolveMemberGenericType (field , 0 );
115+ type .ifPresent (t -> registerAggregateMembers (t , reflectiveClasses ));
116+ } else {
117+ registerAggregateMembers (field .getType (), reflectiveClasses );
118+ }
119+ }
120+ });
66121 }
67122
68123 /**
@@ -80,14 +135,13 @@ private static class MessageHandlerContribution implements BeanFactoryInitializa
80135
81136 private final BindingReflectionHintsRegistrar registrar = new BindingReflectionHintsRegistrar ();
82137
83- private final List <Class <?>> messageHandlingClasses ;
138+ private final Set <Class <?>> messageHandlingClasses ;
84139
85140 private final List <MessageHandlingMember <?>> messageHandlingMembers ;
86141
87142 public MessageHandlerContribution (
88- List <Class <?>> messageHandlingClasses ,
89- List <MessageHandlingMember <?>> messageHandlingMembers
90- ) {
143+ Set <Class <?>> messageHandlingClasses ,
144+ List <MessageHandlingMember <?>> messageHandlingMembers ) {
91145 this .messageHandlingClasses = messageHandlingClasses ;
92146 this .messageHandlingMembers = messageHandlingMembers ;
93147 }
@@ -108,4 +162,26 @@ public void applyTo(GenerationContext generationContext,
108162 });
109163 }
110164 }
165+
166+ @ Priority (Priority .LAST )
167+ private static class LenientParameterResolver implements ParameterResolverFactory , ParameterResolver <Object > {
168+
169+ @ Override
170+ public ParameterResolver <Object > createInstance (Executable executable ,
171+ Parameter [] parameters ,
172+ int parameterIndex ) {
173+ return this ;
174+ }
175+
176+ @ Override
177+ public Object resolveParameterValue (Message message ) {
178+ throw new UnsupportedOperationException (
179+ "This parameter resolver is not mean for production use. Only for detecting handler methods." );
180+ }
181+
182+ @ Override
183+ public boolean matches (Message message ) {
184+ return true ;
185+ }
186+ }
111187}
0 commit comments