Google Guice @Inject、@Inject、@Singleton等注解的用法
1. @Inject 注解
作用
@Inject
是 Guice 的核心注解,用于标记需要依赖注入的地方。它可以作用于构造器、字段和方法。
用法
-
构造器注入
public class Service {@Injectpublic Service(Repository repo) { ... } }
Guice 会自动调用带
@Inject
的构造器,并注入所需依赖。 -
字段注入
public class Service {@Injectprivate Repository repo; }
Guice 会在对象实例化后自动为字段赋值。
-
方法注入
public class Service {private Repository repo;@Injectpublic void setRepository(Repository repo) {this.repo = repo;} }
Guice 会自动调用带
@Inject
的方法并注入参数。
使用场景
任何需要 Guice 自动注入依赖的地方。
注意事项
- 推荐优先使用构造器注入,保证不可变性和更容易测试。
- 字段和方法注入适合处理循环依赖或需要延迟注入的场景。
2. @Singleton 注解
作用
@Singleton
用于声明某个类在 Guice 容器中只创建一个实例,即单例模式。
用法
-
类上使用
@Singleton public class Service { ... }
Guice 会确保该类只实例化一次,后续获取都是同一个对象。
-
绑定时指定作用域
bind(Service.class).in(Singleton.class);
如果类本身没有加注解,也可以在 Module 配置时声明。
使用场景
需要全局唯一实例的服务类、工具类、配置类等。
注意事项
- 单例对象在 Injector 创建时就会初始化,生命周期与 Injector 一致。
- 若有状态,请注意线程安全。
3. @Named 与自定义注解(@BindingAnnotation)
作用
用于区分同一个接口的不同实现,避免注入时混淆。
用法
- @Named(Guice 内置)
bind(PaymentService.class).annotatedWith(Names.named("PayPal")).to(PayPalPaymentService.class);public class OrderService {@Inject@Named("PayPal")PaymentService paymentService; }
- 自定义注解
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME) public @interface PayPal {}bind(PaymentService.class).annotatedWith(PayPal.class).to(PayPalPaymentService.class);public class OrderService {@Inject@PayPalPaymentService paymentService; }
使用场景
同接口多个实现类时,需明确指定注入哪一个。
4. 对比整理
注解 | 作用 | 用法位置 | 典型场景 | 注意事项 |
---|---|---|---|---|
@Inject | 标记需要注入依赖 | 构造器/字段/方法 | 普通依赖注入 | 推荐构造器注入 |
@Singleton | 标记单例作用域 | 类/Module绑定 | 全局唯一实例 | 注意线程安全 |
@Named | 标记命名绑定 | 字段/参数/绑定配置 | 多实现区分 | 字符串容易拼写错误 |
自定义注解 | 标记自定义绑定 | 字段/参数/绑定配置 | 多实现区分 | 需自定义注解类 |
5. 总结建议
- 依赖注入优先用构造器 + @Inject,保证不可变性和易测试。
- 单例用 @Singleton 或 bind(…).in(Singleton.class),保证全局唯一。
- 多实现用 @Named 或自定义注解,保证注入明确。
- Guice 的所有这些注解都是编译时类型安全,便于大型项目维护和扩展。