使用@Inject注解注入
可以通过构造函数和成员变量的方式进行注入,不推荐使用成员变量注入
public class OrderServiceImpl implements OrderService {
// Dependencies
private final PriceService priceService;
// 通过成员变量注入,不推荐
@Inject
private PaymentService paymentService;
private final SessionManager sessionManager;
// 通过构造方法注入
@Inject
public OrderServiceImpl(PriceService priceService, SessionManager sessionManager) {
super();
this.priceService = priceService;
this.sessionManager = sessionManager;
}
}
然后进行绑定具体的实现(后面会讲到绑定)
public class ServerModule extends AbstractModule {
@Override
protected void configure() {
bind(OrderService.class).to(OrderServiceImpl.class);
bind(PaymentService.class).to(PaymentServiceImpl.class);
bind(PriceService.class).to(PriceServiceImpl.class);
}
}
Provider注入
使用provider注入的场景:
- Lazy loading
- 需要多个实例
无需自己实现provider,Guice会考虑对象的生命周期。需要时可以自己实现provider
注入
public class SessionManager {
private final Provider<Long> sessionIdProvider;
@Inject
public SessionManager(Provider<Long> sessionIdProvider) {
super();
this.sessionIdProvider = sessionIdProvider;
}
public Long getSessionId() {
return sessionIdProvider.get();
}
}
使用@Provides绑定
public class ServerModule extends AbstractModule {
@Override
protected void configure() {
bind(OrderService.class).to(OrderServiceImpl.class);
bind(PaymentService.class).to(PaymentServiceImpl.class);
bind(PriceService.class).to(PriceServiceImpl.class);
}
@Provides
Long generateSesssionId() {
return System.currentTimeMillis();
}
}
测试(返回的sessionid值都是不一样的)
public class SessionManagerTest {
@Inject
SessionManager sessionManager;
@Before
public void setUp() {
Guice.createInjector(new ServerModule()).injectMembers(this);
}
@Test
public void testGetSessionId() throws InterruptedException {
Long sessionId1 = sessionManager.getSessionId();
// Pretend we sleep long enough so session expires.
Thread.sleep(1000);
Long sessionId2 = sessionManager.getSessionId();
assertNotEquals(sessionId2.longValue(), sessionId1.longValue());
}
}
命名注入
- 使用@Name("")的方式,主要是为了开发方便
- 使用自定义注解的方式,通常采用该方式
使用自定义注解的方式
@Retention(RetentionPolicy.RUNTIME)
// 必须加BindingAnnotation注解
@BindingAnnotation
public @interface SessionId {
}
绑定
public class ServerModule extends AbstractModule {
@Override
protected void configure() {
bind(OrderService.class).to(OrderServiceImpl.class);
bind(PaymentService.class).to(PaymentServiceImpl.class);
bind(PriceService.class).to(PriceServiceImpl.class);
}
@Provides
@SessionId
Long generateSesssionId() {
return System.currentTimeMillis();
}
}
注入
public class SessionManager {
private final Provider<Long> sessionIdProvider;
@Inject
public SessionManager(@SessionId Provider<Long> sessionIdProvider) {
super();
this.sessionIdProvider = sessionIdProvider;
}
public Long getSessionId() {
return sessionIdProvider.get();
}
}