Class ValueResolver
@Value-annotated injection sites.
Splits the @Value handling into three small pieces so callers (field / parameter / method)
can share the same coercion + error-formatting code without duplicating the lookup logic:
findValueExpression(List)— given an annotation list, return the first@Valueexpression (ornullif no@Valueis present).checkInjectConflict(List, String)— throwBeanCreationExceptionif both@Valueand@Inject/@Autowiredare present on the same site.resolve(String, Class, String)— pass the expression throughVarResolver, coerce to the target type viaSettings.toType(String, Class), and wrap failures inBeanCreationException.
The resolver intentionally uses VarResolver.DEFAULT, which already includes
PropertyVar (the $P{key[,default]} variable that reads from Settings).
After the property-variable unification, the ${key} shortcut routes through that same PropertyVar,
so @Value("${db.url}") and @Value("$P{db.url}") are equivalent.
-
Method Summary
Modifier and TypeMethodDescriptionstatic voidcheckInjectConflict(List<? extends AnnotationInfo<?>> annotations, String siteDescription) ThrowsBeanCreationExceptionif an injection site carries both@Valueand an@Inject/@Autowiredmarker.static voidClears the internalVarTemplatecache.static StringfindValueExpression(List<? extends AnnotationInfo<?>> annotations) Returns thevalue()expression carried by the first@Valueannotation in the list, ornullif no@Value(Juneau or Spring) is present.static VarTemplategetCompiledTemplate(String expression) Returns the compiledVarTemplatefor the given expression, computing and caching on first use.static booleanhasValueAnnotation(List<? extends AnnotationInfo<?>> annotations) Returnstrueif any annotation in the list is a@Valuemarker.static ObjectGeneric-aware@Valueresolution that honorsSupplier<T>field types by returning a re-evaluating, threadsafe Supplier instead of a one-shot resolved value (field-type autodetect — bareStringresolves once,Supplier<T>re-evaluates per.get()).static Objectresolve(String expression, Class<?> targetType, Type genericTargetType, String siteDescription, BeanStore beanStore) Same asresolve(String, Class, Type, String)but consults caller-scopedPropertySourcebeans resolved from the suppliedBeanStore.static ObjectResolves a@Valueexpression against the defaultVarResolverand coerces the result totargetTypeviaSettings.toType(String, Class).static ObjectSame asresolve(String, Class, String)but consults caller-scopedPropertySourcebeans resolved from the suppliedBeanStorebetween theSettingslocal/global override stores and theSettingssources chain.
-
Method Details
-
getCompiledTemplate
Returns the compiledVarTemplatefor the given expression, computing and caching on first use. Intended for use by reflection-layer injection sites (FieldInfo.inject(org.apache.juneau.commons.inject.BeanStore, T),ParameterInfo.resolveValue(org.apache.juneau.commons.inject.BeanStore, java.lang.Object...)) that want to amortize tokenization across repeated bean constructions.- Parameters:
expression- The@Valueexpression text. Must not benull.- Returns:
- The cached compiled template (uses
VarResolver.DEFAULT).
-
clearTemplateCache
Clears the internalVarTemplatecache. Primarily intended for tests that need to exercise the compile-time path repeatedly with differentVarResolvers. Production code should not need to call this. -
findValueExpression
Returns thevalue()expression carried by the first@Valueannotation in the list, ornullif no@Value(Juneau or Spring) is present.- Parameters:
annotations- The annotation list (fromFieldInfo.getAnnotations(),ParameterInfo.getAnnotations(), etc.). May benullor empty, in which casenullis returned.- Returns:
- The expression, or
nullif not a@Valuesite.
-
hasValueAnnotation
Returnstrueif any annotation in the list is a@Valuemarker.- Parameters:
annotations- The annotation list. May benullor empty, in which casefalseis returned.- Returns:
trueif at least one annotation matchesJsrSupport.isValueAnnotation(AnnotationInfo).
-
checkInjectConflict
public static void checkInjectConflict(List<? extends AnnotationInfo<?>> annotations, String siteDescription) ThrowsBeanCreationExceptionif an injection site carries both@Valueand an@Inject/@Autowiredmarker.@Valueresolves strings/primitives;@Injectresolves beans. Combining them on the same site is ambiguous — fail fast with a clear message.- Parameters:
annotations- The annotation list. May benullor empty, in which case this method returns without action.siteDescription- A human-readable description of the site (used in the error message).
-
resolve
Resolves a@Valueexpression against the defaultVarResolverand coerces the result totargetTypeviaSettings.toType(String, Class).Lookup semantics:
- If the resolved value is
nullandtargetTypeis a primitive, throwsBeanCreationException(primitives cannot benull). - If the resolved value is
nullandtargetTypeis a reference type, returnsnull. - If coercion via
Settings.toType(String, Class)fails, the underlying exception is wrapped inBeanCreationExceptionwith a message that includes the expression, the resolved string, and the target type.
- Parameters:
expression- The@Valueexpression (typically"${key}"or"${key:default}"). May benull, in which casenullis returned for reference types (and aBeanCreationExceptionis thrown for primitive target types).targetType- The target Java type. May be a primitive. Must not benull.siteDescription- A human-readable description of the site (used in error messages).- Returns:
- The coerced value.
- If the resolved value is
-
resolve
public static Object resolve(String expression, Class<?> targetType, String siteDescription, BeanStore beanStore) Same asresolve(String, Class, String)but consults caller-scopedPropertySourcebeans resolved from the suppliedBeanStorebetween theSettingslocal/global override stores and theSettingssources chain.The
beanStoreparameter is preserved by-reference; if itsPropertySource-typed contents change between calls, the next resolution picks up the current state. Passingnull(or aBeanStorewith noPropertySource-typed beans) is byte-for-byte equivalent to the zero-argument overload — no extra allocation and no behavior change.- Parameters:
expression- The@Valueexpression. May benull, in which casenullis returned for reference types (and aBeanCreationExceptionis thrown for primitive target types).targetType- The target Java type. May be a primitive. Must not benull.siteDescription- A human-readable description of the site (used in error messages).beanStore- Caller-scopedBeanStoreconsulted forPropertySourcebeans. May benull.- Returns:
- The coerced value.
-
resolve
public static Object resolve(String expression, Class<?> targetType, Type genericTargetType, String siteDescription) Generic-aware@Valueresolution that honorsSupplier<T>field types by returning a re-evaluating, threadsafe Supplier instead of a one-shot resolved value (field-type autodetect — bareStringresolves once,Supplier<T>re-evaluates per.get()).Behavior by
genericTargetType:Supplier<String>→ returns aSupplierthat re-evaluates the compiled template on everySupplier.get()call, each time against a freshVarResolverSession. Safe to share across threads.Supplier<T>forT != String→ returns aSupplierthat, on everySupplier.get()call, re-evaluates the template and coerces the resolved string intoTvia the sameString -> Tconverter machinery that plain@Value Tuses (Settings.toType(String, Class)). The coerced value is never memoized (late-binding contract); coercion failures surface as aRuntimeExceptionfrom.get()naming the@Valuekey and target type.Tis taken from any type the converter registry can build from aString(e.g.Integer,Long,Boolean,Duration,URI,Path, enums).- Anything else (including raw
SupplierandOptional<Supplier<T>>) → delegates toresolve(String, Class, String)with the raw target class (preserves existing behavior; theOptional<Supplier<T>>nesting is intentionally not specially handled).
- Parameters:
expression- The@Valueexpression. May benull.targetType- The erased target class (e.g.String.classorSupplier.class). Must not benull.genericTargetType- The declared generic type (e.g.Supplier<Integer>). May benull, in which case Supplier-detection is skipped.siteDescription- Human-readable site description for error messages.- Returns:
- Either a one-shot coerced value, or a
Supplier<T>factory.
-
resolve
public static Object resolve(String expression, Class<?> targetType, Type genericTargetType, String siteDescription, BeanStore beanStore) Same asresolve(String, Class, Type, String)but consults caller-scopedPropertySourcebeans resolved from the suppliedBeanStore.The
beanStorereference is captured (not snapshotted) by the returnedSupplier<T>when the declared field/parameter type isSupplier<...>, so re-evaluating reads always see the current state ofbeanStore.getBeansOfType(PropertySource.class).- Parameters:
expression- The@Valueexpression. May benull.targetType- The erased target class. Must not benull.genericTargetType- The declared generic type. May benull.siteDescription- Human-readable site description for error messages.beanStore- Caller-scopedBeanStoreconsulted forPropertySourcebeans. May benull.- Returns:
- Either a one-shot coerced value, or a
Supplier<T>factory.
-