@@ -602,8 +602,15 @@ private <T> Object decodeMapIntoObject(int size, Class<T> cls)
602602 parameters [i ] = injectParameter (parameterInjections [i ], parameterTypes [i ]);
603603 continue ;
604604 }
605- if (parameters [i ] == null && parameterDefaults [i ] != null ) {
605+ if (parameters [i ] != null ) {
606+ continue ;
607+ }
608+ if (parameterDefaults [i ] != null ) {
606609 parameters [i ] = parameterDefaults [i ];
610+ continue ;
611+ }
612+ if (shouldInstantiateFromContext (parameterTypes [i ])) {
613+ parameters [i ] = instantiateWithLookupContext (parameterTypes [i ]);
607614 }
608615 }
609616
@@ -629,6 +636,77 @@ private <T> Object decodeMapIntoObject(int size, Class<T> cls)
629636 }
630637 }
631638
639+ private boolean shouldInstantiateFromContext (Class <?> parameterType ) {
640+ if (parameterType == null
641+ || parameterType .isPrimitive ()
642+ || isSimpleType (parameterType )
643+ || Map .class .isAssignableFrom (parameterType )
644+ || List .class .isAssignableFrom (parameterType )) {
645+ return false ;
646+ }
647+ return requiresLookupContext (parameterType );
648+ }
649+
650+ private Object instantiateWithLookupContext (Class <?> parameterType ) {
651+ var metadata = loadConstructorMetadata (parameterType );
652+ if (metadata == null || !metadata .requiresLookupContext ()) {
653+ return null ;
654+ }
655+
656+ var ctor = metadata .constructor ();
657+ var types = metadata .parameterTypes ();
658+ var defaults = metadata .parameterDefaults ();
659+ var injections = metadata .parameterInjections ();
660+ var args = new Object [types .length ];
661+
662+ for (int i = 0 ; i < args .length ; i ++) {
663+ if (injections [i ] != ParameterInjection .NONE ) {
664+ args [i ] = injectParameter (injections [i ], types [i ]);
665+ } else if (defaults [i ] != null ) {
666+ args [i ] = defaults [i ];
667+ } else if (types [i ].isPrimitive ()) {
668+ args [i ] = primitiveDefault (types [i ]);
669+ } else {
670+ args [i ] = null ;
671+ }
672+ }
673+
674+ try {
675+ return ctor .newInstance (args );
676+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException e ) {
677+ throw new DeserializationException (
678+ "Error creating object of type: " + parameterType .getName (), e );
679+ }
680+ }
681+
682+ private static Object primitiveDefault (Class <?> type ) {
683+ if (type .equals (Boolean .TYPE )) {
684+ return false ;
685+ }
686+ if (type .equals (Byte .TYPE )) {
687+ return (byte ) 0 ;
688+ }
689+ if (type .equals (Short .TYPE )) {
690+ return (short ) 0 ;
691+ }
692+ if (type .equals (Integer .TYPE )) {
693+ return 0 ;
694+ }
695+ if (type .equals (Long .TYPE )) {
696+ return 0L ;
697+ }
698+ if (type .equals (Float .TYPE )) {
699+ return 0.0f ;
700+ }
701+ if (type .equals (Double .TYPE )) {
702+ return 0.0d ;
703+ }
704+ if (type .equals (Character .TYPE )) {
705+ return '\0' ;
706+ }
707+ return null ;
708+ }
709+
632710 private Object injectParameter (ParameterInjection injection , Class <?> parameterType ) {
633711 return switch (injection ) {
634712 case IP_ADDRESS -> getLookupIpValue (parameterType );
0 commit comments