dependency injection - mvc - Daga 2: ¿cuál es el propósito de una clase de anotación @Singleton?
mvc dependency injection (4)
De la Documentation la daga 2 noté que puede tener una clase anotada @Singleton
. ¿Cuál es el propósito de marcar una clase como @Singleton
cuando intenté hacer esto en mi código pero NO se produce un objeto singleton? No tengo claro qué uso marcar a mi clase con esta anotación sirve.
De la documentación, por favor enfóquese en la siguiente declaración:
La anotación @Singleton en una clase inyectable también sirve como documentación. Recuerda a los mantenedores potenciales que esta clase puede ser compartida por varios subprocesos. *
@Singleton
class CoffeeMaker {
...
}
ACTUALIZACIÓN: Después de revisar la respuesta de froger_mcs, veo que en Dagger 2 puede proporcionar inyecciones mediante un módulo O mediante una inyección de constructor. Así que la siguiente clase, aunque no en un módulo, puede ser inyectada:
@Singleton
public class MyClass {
@Inject
public MyClass() {
}
}
En esta versión, el constructor se inyecta para nosotros y en una actividad de Android solo haría lo siguiente y se le proporcionará:
@Inject
MyClass myClass;
//then in onCreate actually inject(this) from your graph of course.
@Singleton es hereditario de @Scope, por lo que en la documentación dice
Identifies scope annotations. A scope annotation applies to a class * containing an injectable constructor and governs how the injector reuses * instances of the type. By default, if no scope annotation is present, the * injector creates an instance (by injecting the type''s constructor), uses * the instance for one injection, and then forgets it. If a scope annotation * is present, the injector may retain the instance for possible reuse in a * later injection. If multiple threads can access a scoped instance, its * implementation should be thread safe. The implementation of the scope * itself is left up to the injector. <p>In the following example, the scope annotation {@code @Singleton} ensures * that we only have one Log instance: * * <pre> * @Singleton * class Log { * void log(String message) { ... } * }</pre>
¿Entiendes el punto correcto? Cualquiera sea la anotación que use o cree una personalizada, y la heredarán de @Scope se asegurará como singleton.
Bueno, puedes crear manualmente una anotación, lo que ayudará a crear un objeto singleton .
@Scope
@Retention(RetentionPolicy.CLASS)
public @interface MyApplicationScope {
}
Cuando se agrega la anotación @Provides
con la anotación @Provides
se crea una daga para crear un objeto solo una vez y usar el mismo objeto en el futuro. Recuerde agregar esta anotación a la interfaz del componente, de lo contrario obtendrá el error relacionado con el alcance durante la compilación.
Si está utilizando la anotación @Singleton
, puede terminar creando los nuevos objetos cada vez que cree su componente con .build()
.
@Singleton
(y cualquier otra anotación de alcance) hace que su clase sea una instancia única en su gráfico de dependencias (significa que esta instancia será "singleton" mientras exista el objeto Component).
En resumen, cada vez que esté inyectando la clase anotada @Singleton
(con la anotación @Inject
) será la misma instancia siempre que la inyecte desde el mismo Componente.
Para más información, @Singleton
mi blog sobre cómo @Singleton
anotaciones de @Singleton
y otros ámbitos en Dagger 2: http://frogermcs.github.io/dependency-injection-with-dagger-2-custom-scopes/
@Singleton
no crea realmente un Singleton, es solo un Scope
, se recomienda no usar @Singleton
ya que es engañoso, da la impresión de que de hecho estamos obteniendo un Singleton, pero no lo estamos haciendo.
Digamos que usted anota su dependencia de base de datos con @Singleton
y se vincula con un Component
, ahora digamos que inicializa este Component
en las Activities
A
y B
, tendrá diferentes instancias de su base de datos en sus dos Activities
cual es algo que la mayoría de la gente no tiene. querer.
Cómo superas esto?
Inicialice su Component
una vez en su clase de Application
y acceda a él de forma estática en otros lugares como Activities
o Fragments
, ahora esto podría salirse de control si tiene más de 20 Component''s
ya que no puede inicializarlos todos en su clase de Application
. también ralentizar el tiempo de lanzamiento de su aplicación.
La mejor solución para mí es crear un Singleton
real, ya sea con doble verificación o de otras variantes y usar esto estáticamente como getInstance()
y usarlo bajo @Provides
en su Módulo.
Sé que también me rompe el corazón, pero entiendo que @Singleton
no es realmente un Singleton
, es un Scope
.