Class ValueResolver

java.lang.Object
org.apache.juneau.commons.inject.ValueResolver

public final class ValueResolver extends Object
Internal helper used by the reflection layer to resolve @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:

  1. findValueExpression(List) — given an annotation list, return the first @Value expression (or null if no @Value is present).
  2. checkInjectConflict(List, String) — throw BeanCreationException if both @Value and @Inject/@Autowired are present on the same site.
  3. resolve(String, Class, String) — pass the expression through VarResolver, coerce to the target type via Settings.toType(String, Class), and wrap failures in BeanCreationException.

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 Details

    • getCompiledTemplate

      public static VarTemplate getCompiledTemplate(String expression)
      Returns the compiled VarTemplate for 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 @Value expression text. Must not be null.
      Returns:
      The cached compiled template (uses VarResolver.DEFAULT).
    • clearTemplateCache

      public static void clearTemplateCache()
      Clears the internal VarTemplate cache. Primarily intended for tests that need to exercise the compile-time path repeatedly with different VarResolvers. Production code should not need to call this.
    • findValueExpression

      public static String findValueExpression(List<? extends AnnotationInfo<?>> annotations)
      Returns the value() expression carried by the first @Value annotation in the list, or null if no @Value (Juneau or Spring) is present.
      Parameters:
      annotations - The annotation list (from FieldInfo.getAnnotations(), ParameterInfo.getAnnotations(), etc.). May be null or empty, in which case null is returned.
      Returns:
      The expression, or null if not a @Value site.
    • hasValueAnnotation

      public static boolean hasValueAnnotation(List<? extends AnnotationInfo<?>> annotations)
      Returns true if any annotation in the list is a @Value marker.
      Parameters:
      annotations - The annotation list. May be null or empty, in which case false is returned.
      Returns:
      true if at least one annotation matches JsrSupport.isValueAnnotation(AnnotationInfo).
    • checkInjectConflict

      public static void checkInjectConflict(List<? extends AnnotationInfo<?>> annotations, String siteDescription)
      Throws BeanCreationException if an injection site carries both @Value and an @Inject/@Autowired marker.

      @Value resolves strings/primitives; @Inject resolves beans. Combining them on the same site is ambiguous — fail fast with a clear message.

      Parameters:
      annotations - The annotation list. May be null or empty, in which case this method returns without action.
      siteDescription - A human-readable description of the site (used in the error message).
    • resolve

      public static Object resolve(String expression, Class<?> targetType, String siteDescription)
      Resolves a @Value expression against the default VarResolver and coerces the result to targetType via Settings.toType(String, Class).

      Lookup semantics:

      • If the resolved value is null and targetType is a primitive, throws BeanCreationException (primitives cannot be null).
      • If the resolved value is null and targetType is a reference type, returns null.
      • If coercion via Settings.toType(String, Class) fails, the underlying exception is wrapped in BeanCreationException with a message that includes the expression, the resolved string, and the target type.
      Parameters:
      expression - The @Value expression (typically "${key}" or "${key:default}"). May be null, in which case null is returned for reference types (and a BeanCreationException is thrown for primitive target types).
      targetType - The target Java type. May be a primitive. Must not be null.
      siteDescription - A human-readable description of the site (used in error messages).
      Returns:
      The coerced value.
    • resolve

      public static Object resolve(String expression, Class<?> targetType, String siteDescription, BeanStore beanStore)
      Same as resolve(String, Class, String) but consults caller-scoped PropertySource beans resolved from the supplied BeanStore between the Settings local/global override stores and the Settings sources chain.

      The beanStore parameter is preserved by-reference; if its PropertySource-typed contents change between calls, the next resolution picks up the current state. Passing null (or a BeanStore with no PropertySource-typed beans) is byte-for-byte equivalent to the zero-argument overload — no extra allocation and no behavior change.

      Parameters:
      expression - The @Value expression. May be null, in which case null is returned for reference types (and a BeanCreationException is thrown for primitive target types).
      targetType - The target Java type. May be a primitive. Must not be null.
      siteDescription - A human-readable description of the site (used in error messages).
      beanStore - Caller-scoped BeanStore consulted for PropertySource beans. May be null.
      Returns:
      The coerced value.
    • resolve

      public static Object resolve(String expression, Class<?> targetType, Type genericTargetType, String siteDescription)
      Generic-aware @Value resolution that honors Supplier<T> field types by returning a re-evaluating, threadsafe Supplier instead of a one-shot resolved value (field-type autodetect — bare String resolves once, Supplier<T> re-evaluates per .get()).

      Behavior by genericTargetType:

      • Supplier<String> → returns a Supplier that re-evaluates the compiled template on every Supplier.get() call, each time against a fresh VarResolverSession. Safe to share across threads.
      • Supplier<T> for T != String → returns a Supplier that, on every Supplier.get() call, re-evaluates the template and coerces the resolved string into T via the same String -> T converter machinery that plain @Value T uses (Settings.toType(String, Class)). The coerced value is never memoized (late-binding contract); coercion failures surface as a RuntimeException from .get() naming the @Value key and target type. T is taken from any type the converter registry can build from a String (e.g. Integer, Long, Boolean, Duration, URI, Path, enums).
      • Anything else (including raw Supplier and Optional<Supplier<T>>) → delegates to resolve(String, Class, String) with the raw target class (preserves existing behavior; the Optional<Supplier<T>> nesting is intentionally not specially handled).
      Parameters:
      expression - The @Value expression. May be null.
      targetType - The erased target class (e.g. String.class or Supplier.class). Must not be null.
      genericTargetType - The declared generic type (e.g. Supplier<Integer>). May be null, 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 as resolve(String, Class, Type, String) but consults caller-scoped PropertySource beans resolved from the supplied BeanStore.

      The beanStore reference is captured (not snapshotted) by the returned Supplier<T> when the declared field/parameter type is Supplier<...>, so re-evaluating reads always see the current state of beanStore.getBeansOfType(PropertySource.class).

      Parameters:
      expression - The @Value expression. May be null.
      targetType - The erased target class. Must not be null.
      genericTargetType - The declared generic type. May be null.
      siteDescription - Human-readable site description for error messages.
      beanStore - Caller-scoped BeanStore consulted for PropertySource beans. May be null.
      Returns:
      Either a one-shot coerced value, or a Supplier<T> factory.