File: QualifierOrScopeOnInjectMethod.md

package info (click to toggle)
error-prone-java 2.18.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 23,204 kB
  • sloc: java: 222,992; xml: 1,319; sh: 25; makefile: 7
file content (72 lines) | stat: -rw-r--r-- 2,642 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
The `@Inject` annotation is applied to **injection points** - methods,
constructors, or fields that a dependency injection tool like Guice or Dagger
will invoke or populate to construct an object.

Scope annotations (annotations that are themselves annotated with
`@ScopeAnnotation`) are used to denote the 'effective scope' of an object.
Examples of scope annotations include `@Singleton`, `@RequestScope`,
`@SessionScope`. These annotations can be used either on the declaration of a
type (so that every instantiation of that object will be handled with the
appropriate scope), or on a **provider method** (to declare that the particular
binding declared by that provider method is subject to that annotation's scoping
rules):

```java
@Singleton
class ExpensiveGlobalObject {
    @Inject ExpensiveGlobalObject(SomeDependencies stuff) {...}
}

class SomeModule extends AbstractModule {
    ...
    @Provides
    @Singleton
    OtherExpensiveObject provideOtherExpensiveObject() { return new Gold(); }
}
```

Qualifier annotations (annotations that are themselves annotated with
`@Qualifier` or `@BindingAnnotation`) are used to distinguish different
instances of the same type of object (the `@Red Robot` instead of the `@Blue
Robot`). These annotations can be used _inside_ injection points, or on those
provider methods:

```java
class RobotArena {
    @Inject RobotArena(@Red Robot redBot, @Blue Robot blueBot) {...}
}

class SomeModule extends AbstractModule {
    ...
    @Provides
    @Red
    Robot provideRedRobot() { return new Robot("red"); }
}
```

Notably: there is no method declaration where `@Inject` and either a scope or a
qualifier annotation can reasonably coexist. Either the method is an **injection
point**, and the dependency injection system will ignore the scope or qualifier
annotation, or the method is a **provider** method, and the `@Inject` method
won't have any effect, as modules are constructed without a dependency injection
container.

```java
class Example {
  // Here, @Singleton is ignored. Perhaps the scope should go onto Example, to make dependency
  // injection systems treat the Example type as a singleton.
  @Inject @Singleton
  Example(Robot something) {}
}
```

```java
class MyModule extends AbstractModule {
  ...
  // The `@Inject` doesn't do anything: Guice will use this method to define a Singleton binding
  // for Database. When a Database is constructed by Guice, a DatabaseCredentials will be
  // constructed and this method will be invoked, but it isn't invoked until then.
  @Provides @Singleton @Inject
  Database providesSingletonDatabase(DatabaseCredentials db) { ... }
}
```