{"record":{"id":"595724f10409ef43","repo":"spring-projects/spring-framework","slug":"unsatisfied-dependency-expressed-through-injection","errorCode":null,"errorMessage":"Unsatisfied dependency expressed through injection point","messagePattern":"Unsatisfied dependency expressed through injection point","errorType":"exception","errorClass":"UnsatisfiedDependencyException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java","lineNumber":341,"sourceCode":"\t\tValueHolder resolvedHolder = new ValueHolder(value, valueHolder.getType(), valueHolder.getName());\n\t\tresolvedHolder.setSource(valueHolder);\n\t\treturn resolvedHolder;\n\t}\n\n\tprivate @Nullable Object resolveAutowiredArgument(RegisteredBean registeredBean, DependencyDescriptor descriptor,\n\t\t\t@Nullable ValueHolder argumentValue, Set<String> autowiredBeanNames) {\n\n\t\tTypeConverter typeConverter = registeredBean.getBeanFactory().getTypeConverter();\n\t\tif (argumentValue != null) {\n\t\t\treturn (argumentValue.isConverted() ? argumentValue.getConvertedValue() :\n\t\t\t\t\ttypeConverter.convertIfNecessary(argumentValue.getValue(),\n\t\t\t\t\t\t\tdescriptor.getDependencyType(), descriptor.getMethodParameter()));\n\t\t}\n\t\ttry {\n\t\t\treturn registeredBean.resolveAutowiredArgument(descriptor, typeConverter, autowiredBeanNames);\n\t\t}\n\t\tcatch (BeansException ex) {\n\t\t\tthrow new UnsatisfiedDependencyException(null, registeredBean.getBeanName(), descriptor, ex);\n\t\t}\n\t}\n\n\tprivate Object instantiate(RegisteredBean registeredBean, Executable executable, @Nullable Object[] args) {\n\t\tif (executable instanceof Constructor<?> constructor) {\n\t\t\tif (registeredBean.getBeanFactory() instanceof DefaultListableBeanFactory dlbf &&\n\t\t\t\t\tregisteredBean.getMergedBeanDefinition().hasMethodOverrides()) {\n\t\t\t\treturn dlbf.getInstantiationStrategy().instantiate(registeredBean.getMergedBeanDefinition(),\n\t\t\t\t\t\tregisteredBean.getBeanName(), registeredBean.getBeanFactory());\n\t\t\t}\n\t\t\treturn BeanUtils.instantiateClass(constructor, args);\n\t\t}\n\t\tif (executable instanceof Method method) {\n\t\t\tObject target = null;\n\t\t\tString factoryBeanName = registeredBean.getMergedBeanDefinition().getFactoryBeanName();\n\t\t\tif (factoryBeanName != null) {\n\t\t\t\ttarget = registeredBean.getBeanFactory().getBean(factoryBeanName, method.getDeclaringClass());\n\t\t\t}","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java#L323-L359","documentation":"Thrown as an UnsatisfiedDependencyException when the AOT BeanInstanceSupplier cannot resolve an autowired argument of the bean's constructor or factory method. In resolveAutowiredArgument, the supplier delegates to RegisteredBean.resolveAutowiredArgument; if that throws a BeansException (no candidate, ambiguous, conversion failure), it is wrapped with the bean name and the DependencyDescriptor so the failing injection point is visible.","triggerScenarios":"Invoking a generated BeanInstanceSupplier whose underlying constructor/factory method has arguments that beanFactory.resolveDependency cannot satisfy at runtime. Common when an autowired constructor parameter has no qualifying bean, multiple candidates without @Primary/@Qualifier, or an unconvertible value.","commonSituations":"Bean instantiated by AOT supplier whose constructor needs a collaborator that was not registered in the trimmed native-image context; constructor-injected @Value with an unresolved placeholder; multiple DataSource/RestTemplate-style beans with no disambiguation; bean class changed signature in a new version but the AOT metadata is stale.","solutions":["Look at the DependencyDescriptor in the exception to find the constructor/factory-method parameter that failed, then register or qualify a bean of that type.","Add @Qualifier or @Primary to disambiguate when multiple candidates of the parameter type exist.","Verify @Value placeholders resolve and that a PropertySourcesPlaceholderConfigurer/Environment is present in the native image.","If the parameter is optional, make it Optional<T>, ObjectProvider<T>, or mark @Autowired(required=false) as appropriate for the injection point.","Regenerate AOT artifacts (clean native build) after changing the bean class to avoid stale metadata."],"exampleFix":"// before: constructor needs a missing collaborator -> UnsatisfiedDependencyException\npublic OrderService(PaymentGateway gateway) { ... }\n\n// after: register the bean and disambiguate\n@Bean\n@Primary\npublic PaymentGateway stripeGateway() { ... }","handlingStrategy":"try-catch","validationCode":"// Pre-check that constructor/factory-method arguments are resolvable\nfor (Class<?> pt : executable.getParameterTypes()) {\n    if (bf.getBeanNamesForType(pt).length == 0 && !isOptional(pt)) {\n        throw new IllegalStateException(\"Missing bean for constructor arg: \" + pt);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return instanceSupplier.get(registeredBean);\n} catch (UnsatisfiedDependencyException ex) {\n    throw new ConfigurationException(\"Cannot instantiate \" + registeredBean.getBeanName(), ex);\n}","preventionTips":["Use constructor injection with mandatory collaborators so missing beans fail at startup.","Add @Primary or @Qualifier to disambiguate ambiguous constructor parameters.","Write an integration test that loads the context in AOT mode.","Keep AOT metadata in sync with bean class signatures."],"tags":["spring","aot","dependency-injection","constructor-injection","native-image"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}