Annotation Type RestrictedBindingSource
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:
- 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.
- 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
- Author:
- vzm@google.com (Vladimir Makaric)
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic @interface
Meta-annotation indicating that the target annotation is a permit for binding restricted bindings.static enum
Level of restriction. -
Required Element Summary
Required ElementsModifier and TypeRequired ElementDescriptionExplanation of why binding this target type is restricted.Class<? extends Annotation>[]
List ofPermit
annotations (must be non-empty), one of which has has to be present on a restricted binding's source (defined in top-level javadoc). -
Optional Element Summary
Optional ElementsModifier and TypeOptional ElementDescriptionExempt modules whose fully qualified class names match this regex.
-
Element Details
-
explanation
String explanationExplanation 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>[] permitsList ofPermit
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 exemptModulesExempt 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:
""
-
restrictionLevel
RestrictedBindingSource.RestrictionLevel restrictionLevel- Default:
ERROR
-