一、Guice 的基本原理
Guice 通过 Java 注解(如 @Inject
)和模块(Module)来描述对象的依赖关系。它在应用启动时,自动分析依赖,并为你创建和注入所需的对象实例。
- 依赖注入(DI):将对象的创建和依赖转交给框架管理,降低耦合。
- 控制反转(IoC):对象不再主动获取依赖,而是由容器(Guice)主动提供。
二、核心概念与结构
@Inject 注解
- 标记需要注入的构造器、字段或方法。
- 例如:
class Service { @Inject public Service(Repository repo) { ... } }
Module(模块)
- 通过继承
AbstractModule
,在configure()
方法中绑定接口与实现。 - 例如:
public class AppModule extends AbstractModule { @Override protected void configure() { bind(Repository.class).to(RepositoryImpl.class); } }
- 通过继承
Injector(注入器)
- Guice 的容器,用于创建和管理对象实例。
- 例如:
Injector injector = Guice.createInjector(new AppModule()); Service service = injector.getInstance(Service.class);
Provider(提供者)
- 用于复杂或需要动态创建的依赖。
- 例如:
public class MyProvider implements Provider<Repository> { public Repository get() { ... } }
@Singleton(单例)
- 标记该类只创建一个实例。
- 例如:
@Singleton class Service { ... }
三、常用用法详解
1. 构造器注入
class UserService {
private final UserRepository userRepository;
@Inject
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
2. 字段注入
class UserService {
@Inject
UserRepository userRepository;
}
3. 方法注入
class UserService {
private UserRepository userRepository;
@Inject
public void setUserRepository(UserRepository repo) {
this.userRepository = repo;
}
}
4. 绑定接口到实现
在模块中配置:
public class AppModule extends AbstractModule {
@Override
protected void configure() {
bind(UserRepository.class).to(UserRepositoryImpl.class);
}
}
5. 绑定到特定实例
bind(String.class).toInstance("Hello Guice!");
6. 使用 Provider
bind(UserRepository.class).toProvider(UserRepositoryProvider.class);
7. 作用域管理
单例:
bind(UserService.class).in(Singleton.class);
或者直接在类上加 @Singleton
注解。
四、进阶用法
1. 命名绑定(@Named)
当有多个实现时,可以用 @Named
区分:
bind(PaymentService.class).annotatedWith(Names.named("PayPal")).to(PayPalPaymentService.class);
class OrderService {
@Inject
@Named("PayPal")
PaymentService paymentService;
}
2. 自定义注解绑定
@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface PayPal {}
bind(PaymentService.class).annotatedWith(PayPal.class).to(PayPalPaymentService.class);
class OrderService {
@Inject
@PayPal
PaymentService paymentService;
}
3. 多重绑定(Multibinder)
用于集合注入:
Multibinder<PaymentService> multibinder = Multibinder.newSetBinder(binder(), PaymentService.class);
multibinder.addBinding().to(PayPalPaymentService.class);
multibinder.addBinding().to(AlipayPaymentService.class);
@Inject
Set<PaymentService> paymentServices;
4. 生命周期管理
Guice 本身不直接管理对象销毁,但支持 JSR-250(如 @PreDestroy
)。
五、Guice 与 Spring 比较
- Guice 更轻量,专注于依赖注入,配置简单。
- Spring 功能更全,支持 AOP、事务等,适合大型企业应用。
- Guice 适合微服务、轻量级项目或对性能敏感的场景。
六、完整示例
// 接口
public interface UserRepository {
void save(User user);
}
// 实现
public class UserRepositoryImpl implements UserRepository {
public void save(User user) { System.out.println("User saved!"); }
}
// 服务
public class UserService {
private final UserRepository userRepository;
@Inject
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void register(User user) {
userRepository.save(user);
}
}
// 模块
public class AppModule extends AbstractModule {
@Override
protected void configure() {
bind(UserRepository.class).to(UserRepositoryImpl.class);
}
}
// 启动
public class Main {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AppModule());
UserService service = injector.getInstance(UserService.class);
service.register(new User());
}
}
七、常见问题
- 循环依赖:Guice 不直接支持构造器循环依赖,但可以用
Provider
或字段注入解决。 - 配置热更新:Guice 本身不支持,需要自定义实现。
- AOP:Guice 支持方法拦截(见
MethodInterceptor
),但功能不如 Spring 全面。
八、更多资源
- Guice 官方文档
- Guice 中文教程
- 《Google Guice权威指南》
如需针对某一功能或场景深入讲解,欢迎进一步提问!