Annotation Type RestrictedBindingSource


  • @Inherited
    @Retention(RUNTIME)
    @Target(TYPE)
    public @interface RestrictedBindingSource
    Annotation restricting the binding of the target type to permitted sources.

    Bindings restricted by this annotation may only be created by sources annotated with a permit from permits() -- otherwise, an error message including the explanation() is issued.

    There are two kinds of binding source:

    1. Module: a module is the source of a binding if it creates it (either directly, or indirectly by installing another module). For example: if module A creates restricted binding X, and module C installs module B that installs A; then all 3 modules C,B,A are sources of X, and it's enough for any one of them to be annotated with a permit from X's restriction.
    2. Method Scanner (ModuleAnnotatedMethodScanner): If a binding was created by a scanner, then that scanner is also a source of the binding (in addition to the module sources) and a permit may be given to the scanner by annotating its class.

    Bindings with qualifier annotations are restricted solely by the annotation on their qualifier (restrictions on the type are ignored for qualified bindings). Unqualified bindings are restricted by the annotation on their type.

    This allows libraries to prevent their clients from binding their keys, similar to how declaring a class final prevents subtyping. For example, a library may want to prevent users from creating mock bindings for tests, using the explanation() - included in the error message - to point them to a supported testing module.

    Example usage:

     @RestrictedBindingSource.Permit
     @Retention(RetentionPolicy.RUNTIME)
     @interface NetworkPermit {}
    
     @RestrictedBindingSource(
       explanation = "Only NetworkModule can create network bindings.",
       permits = {NetworkPermit.class})
     @Qualifier
     @Retention(RetentionPolicy.RUNTIME)
     public @interface GatewayIpAdress {}
    
     @NetworkPermit
     public final class NetworkModule extends AbstractModule {
       // Allowed because the module is annotated with @NetworkPermit.
       @Provides
       @GatewayIpAdress
       int provideGatewayIp() { ... }
     }
     
    Since:
    5.0
    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element Description
      String explanation
      Explanation of why binding this target type is restricted.
      Class<? extends Annotation>[] permits
      List of Permit annotations (must be non-empty), one of which has has to be present on a restricted binding's source (defined in top-level javadoc).
    • Element Detail

      • explanation

        String explanation
        Explanation of why binding this target type is restricted.

        Will appear as the error message if the target type is bound by non-allowed modules.

      • permits

        Class<? extends Annotation>[] permits
        List of Permit annotations (must be non-empty), one of which has has to be present on a restricted binding's source (defined in top-level javadoc).
      • exemptModules

        String exemptModules
        Exempt modules whose fully qualified class names match this regex.

        If any module on the binding's module stack matches this regex, the binding is allowed (no permit necessary). No module is exempt by default (empty string).

        Inteded to be used when retrofitting a binding with this restriction. When restricting an existing binding, it's often practical to first restrict with exemptions for existing violations (to prevent new violations), before updating the code in violation to use the permitted module(s).

        Default:
        ""