Class InjectionFramework

java.lang.Object
build.codemodel.dependency.injection.InjectionFramework

public class InjectionFramework extends Object
A JDKCodeModel-based Adapter allowing the runtime discovery of InjectionPoints and JSR-330-compliant Dependency Injection of Classes and Objects
Since:
Oct-2024
Author:
brian.oliver
  • Constructor Details

    • InjectionFramework

      public InjectionFramework(build.codemodel.jdk.JDKCodeModel codeModel)
      Constructs an InjectionFramework.
      Parameters:
      codeModel - the JDKCodeModel
  • Method Details

    • create

      public static InjectionFramework create()
      Creates an InjectionFramework with a default non-caching JDKCodeModel.
      Returns:
      a new InjectionFramework
    • codeModel

      public build.codemodel.jdk.JDKCodeModel codeModel()
      Obtains the JDKCodeModel used by InjectionFramework.
      Returns:
      the JDKCodeModel
    • hasQualifierAnnotation

      public boolean hasQualifierAnnotation(build.codemodel.jdk.descriptor.JDKTypeDescriptor annotationTypeDescriptor)
      Determines if the specified JDKTypeDescriptor, usually for an Annotation, is annotated with Qualifier.
      Parameters:
      annotationTypeDescriptor - the JDKTypeDescriptor
      Returns:
      true if the JDKTypeDescriptor has a Qualifier annotation, false otherwise
    • getQualifierAnnotationTypes

      public Stream<build.codemodel.foundation.usage.AnnotationTypeUsage> getQualifierAnnotationTypes(build.codemodel.foundation.descriptor.Traitable traitable)
      Determines the AnnotationTypeUsages of the specified Traitable that have the Qualifier meta-annotation.
      Parameters:
      traitable - Traitable
      Returns:
      the Stream of Qualifier AnnotationTypeUsages
    • getInjectableDescriptor

      public InjectableDescriptor getInjectableDescriptor(Class<?> injectableClass)
      Obtains the InjectableDescriptor for the specified Class, using the JDKCodeModel if necessary to establish one.
      Parameters:
      injectableClass - the Class
      Returns:
      the InjectableDescriptor for the Class
    • getInjectableDescriptor

      public InjectableDescriptor getInjectableDescriptor(build.codemodel.jdk.descriptor.JDKTypeDescriptor typeDescriptor)
      Obtains the InjectableDescriptor for the specified JDKTypeDescriptor, using the JDKTypeDescriptor if necessary to establish one.
      Parameters:
      typeDescriptor - the JDKTypeDescriptor
      Returns:
      the InjectableDescriptor for the JDKTypeDescriptor
    • isInjectionPoint

      public boolean isInjectionPoint(build.codemodel.foundation.descriptor.Traitable traitable)
      Determines if a Traitable represents an InjectionPoint, which means it is non-static, non-abstract with an AnnotationTypeUsage for Inject.
      Parameters:
      traitable - the Traitable
      Returns:
      true if the Traitable contains an Inject use, false otherwise
    • isSingleton

      public boolean isSingleton(build.codemodel.jdk.descriptor.JDKTypeDescriptor typeDescriptor)
      Determines if the specified JDKTypeDescriptor is annotated as a Singleton.
      Parameters:
      typeDescriptor - the JDKTypeDescriptor
      Returns:
      true if annotated as a Singleton, otherwise false
    • isPostInject

      public boolean isPostInject(build.codemodel.objectoriented.descriptor.MethodDescriptor descriptor)
      Determines if a MethodDescriptor represents an PostInject method, which means it is non-static, non-abstract with an AnnotationTypeUsage for PostInject.
      Parameters:
      descriptor - the MethodDescriptor
      Returns:
      true if the Traitable contains an Inject use, false otherwise
    • isPreDestroy

      public boolean isPreDestroy(build.codemodel.objectoriented.descriptor.MethodDescriptor descriptor)
      Determines if a MethodDescriptor represents a PreDestroy method.
      Parameters:
      descriptor - the MethodDescriptor
      Returns:
      true if annotated with PreDestroy
    • bindScope

      public void bindScope(Class<? extends Annotation> scopeAnnotation, Scope scope)
      Registers a Scope implementation for the specified scope annotation type. The scope is applied whenever a class annotated with scopeAnnotation is bound via Binder.bind(Class).
      Parameters:
      scopeAnnotation - the scope annotation class (must be annotated with ScopeAnnotation)
      scope - the Scope implementation to register
    • findScopeEntry

      public Optional<Map.Entry<Class<? extends Annotation>, Scope>> findScopeEntry(build.codemodel.jdk.descriptor.JDKTypeDescriptor typeDescriptor)
      Returns the registered scope entry (annotation class + Scope) for the given JDKTypeDescriptor, if the type carries a scope annotation that has been registered via bindScope(Class, Scope).
      Parameters:
      typeDescriptor - the type descriptor to inspect
      Returns:
      an Optional containing the matching entry, or empty if none
    • findScope

      public Optional<Scope> findScope(build.codemodel.jdk.descriptor.JDKTypeDescriptor typeDescriptor)
      Returns the registered Scope for the given JDKTypeDescriptor, if the type carries a scope annotation that has been registered via bindScope(Class, Scope).
      Parameters:
      typeDescriptor - the type descriptor to inspect
      Returns:
      an Optional containing the matching Scope, or empty if none
    • withBindingGraph

      public InjectionFramework withBindingGraph()
      Installs a GraphBuildingContributor and returns this framework for fluent chaining. Every context created by this framework will contribute its bindings and resolved dependencies to the graph, which can then be snapshotted via Context.snapshot(Path).
      Returns:
      this InjectionFramework
    • setBindingGraphContributor

      public void setBindingGraphContributor(BindingGraphContributor contributor)
      Installs a BindingGraphContributor that will be notified of every binding registration and dependency resolution for all contexts created by this framework. Replaces the default BindingGraphContributor.NOOP.
      Parameters:
      contributor - the contributor to install; must not be null
    • isProvides

      public boolean isProvides(build.codemodel.objectoriented.descriptor.MethodDescriptor descriptor)
      Determines if a MethodDescriptor represents a Provides method, which means it is non-static, non-abstract, non-void with an AnnotationTypeUsage for Provides.

      This is a descriptor-level predicate intended for use when scanning a JDKTypeDescriptor to identify provider methods before constructing a ProvidesResolver. It only recognizes a method that carries the Provides annotation itself; it does not recognize a concrete override of an abstract Provides method that omits the annotation. For that, use resolveEffectivelyProvides(Collection), which is what ProvidesResolver uses internally.

      Parameters:
      descriptor - the MethodDescriptor
      Returns:
      true if the MethodDescriptor has a Provides annotation, false otherwise
    • resolveEffectivelyProvides

      public Stream<build.codemodel.objectoriented.descriptor.MethodDescriptor> resolveEffectivelyProvides(Collection<build.codemodel.objectoriented.descriptor.MethodDescriptor> allMethods)
      Determines the non-static, non-abstract MethodDescriptors within allMethods that are effectively Provides methods - either because they carry the Provides annotation themselves, or because they override an abstract method elsewhere in allMethods that does.

      An abstract method has no way to "opt out" of being overridden - unlike an Inject method, every concrete subclass is forced to supply an implementation - so requiring Provides to be repeated on every concrete override of an abstract Provides method is pure boilerplate, and forgetting to do so silently drops the provider rather than reporting an error.

      Parameters:
      allMethods - the MethodDescriptors to inspect, typically the result of scanning a JDKTypeDescriptor's hierarchy
      Returns:
      the Stream of effectively-Provides MethodDescriptors
    • newContext

      public Context newContext()
      Creates a new empty Context.
      Returns:
      a new Context
    • newContext

      public Context newContext(Resolver<?>... resolvers)
      Creates a new Context initialized with the specified Resolvers.
      Parameters:
      resolvers - the Resolvers
      Returns:
      a new Context
    • newContext

      public Context newContext(Module... modules)
      Creates a new Context with the specified Modules pre-installed.
      Parameters:
      modules - the Modules to install
      Returns:
      a new Context