Guice与Spring 相比,属于轻量级框架,更轻,帮助我们解决Java项目中的依赖注入问题。如果仅需要解决依赖和注入问题的话,就应该考虑一下它,而不是直接Spring走起
谈论:注入首先来设定场景,假设有一个订单场景,当然,我们只为了展示注入而设定一个微小的代码段;
ps: 文中所用maven配置
UTF-8
1.8
1.8
1.8
junit
junit
3.8.1
test
com.google.inject
guice
4.2.0
com.google.inject.extensions
guice-multibindings
4.2.0
(Guice的扩展Multibindings,可以做到多个Module共同Bind一个Set)
建立一个业务接口:OrderService.class 用于描述场景
public interface OrderService {
void sendToPayment(long orderId);
}
业务实现类:OrderServerImpl.class
import javax.inject.Inject; //引用javax的是因为guice已经对其进行实现
import CoffeeAndIce.GuiceDemo.server.OrderService;
import CoffeeAndIce.GuiceDemo.server.PaymentService;
import CoffeeAndIce.GuiceDemo.server.PriceService;
public class OrderServerImpl implements OrderService {
//Dependencies
private final PriceService priceService;
private final PaymentService paymentService;
private final SessionManager sessionManager;
//States
private Long ordersPaid = 0L;
@Inject
public OrderServerImpl(PriceService priceService,
PaymentService paymentService,
SessionManager sessionManager) {
super();
this.priceService = priceService;
this.paymentService = paymentService;
this.sessionManager = sessionManager;
}
public void sendToPayment(long orderId) {
long price = priceService.getPrice(orderId);
paymentService.pay(orderId, price, sessionManager.getSessionId());
ordersPaid = ordersPaid + 1;
throw new RuntimeException("Price" + price
+ ".SessionId=" + sessionManager.getSessionId()
+ "orderPaid=" + ordersPaid);
}
}
其余实现类仅返回一个简单Long,接口有了,实现类也有了,接下来就是如何将接口和实现类关联的问题了,在Guice中需要定义Module来进行关联,注入的配置是自写的Java类,必须继承AbstractModule抽象类,实现configure()方法
public class ServerModule extends AbstractModule{
@Override
protected void configure() {
bind(OrderService.class).to(OrderServerImpl.class);//相当于将实现类注入
bind(PaymentService.class).to(PaymentServiceImpl.class);
bind(PriceService.class).to(PriceServiceImpl.class);
}
}
对于SessionManager,我们也可以这样注入:
public class SessionManager {
private final Long sessionId;
@Inject
public SessionManager(Long sessionId) {
super();
this.sessionId = sessionId;
}
public Long getSessionId() {
// TODO Auto-generated method stub
return sessionId;
}
}
public class ServerModule extends AbstractModule{
@Override
protected void configure() {
bind(OrderService.class).to(OrderServerImpl.class);
bind(PaymentService.class).to(PaymentServiceImpl.class);
bind(PriceService.class).to(PriceServiceImpl.class);
// bind(Long.class).toInstance(1234L); //方式一
;
}
@Provides Long generateSessionId(){//方式二,名字可以随便起,当且仅有一个类型注入
return 1234L;
}
private final Provider SessionIdProvider;
@Inject
public SessionManager(Provider SessionIdProvider) {
super();
this.SessionIdProvider = SessionIdProvider;
}
public Long getSessionId() {
// TODO Auto-generated method stub
return SessionIdProvider.get();
}
@Override
protected void configure() {
bind(OrderService.class).to(OrderServerImpl.class);
bind(PaymentService.class).to(PaymentServiceImpl.class);
bind(PriceService.class).to(PriceServiceImpl.class);
// bind(Long.class).toInstance(1234L);//方式一
bind(Long.class).toProvider(new Provider() {//方式二
@Override
public Long get() {
return 1234L;
}
});
}
// @Provides @SessionId Long generateSessionId(){//方式三,名字可以随便起,当且仅当仅一个类型时
// return 1234L;
// }
可以直接用@Named("getCurrentTimes") ,内容自填,注入的时候只关注名字与类型匹配
还可以自定义:
@SessionId
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import com.google.inject.BindingAnnotation;
@Retention(RetentionPolicy.RUNTIME)//运行时起作用
@BindingAnnotation //让其绑定注释
public @interface SessionId {
}
SessionManager.class
public class SessionManager {
private final Provider SessionIdProvider;
@Inject
public SessionManager(@SessionId Provider SessionIdProvider) {
super();
this.SessionIdProvider = SessionIdProvider;
}
public Long getSessionId() {
// TODO Auto-generated method stub
return SessionIdProvider.get();
}
}
ServerModule.class
public class ServerModule extends AbstractModule{
@Override
protected void configure() {
bind(OrderService.class).to(OrderServerImpl.class);
bind(PaymentService.class).to(PaymentServiceImpl.class);
bind(PriceService.class).to(PriceServiceImpl.class);
// bind(Long.class).annotatedWith(SessionId.class).toInstance(1234L);;//方式一 ,用这种方式,生成configure的时候已经固定数值
// bind(Long.class).annotatedWith(SessionId.class).toProvider(new Provider() {//方式二
//
// @Override
// public Long get() {
// return 1234L;
// }
// });
}
@Provides @SessionId Long generateSessionId(){//方式三,名字可以随便起,当且仅当仅一个类型时
return 1234L;
}
}
(四)测试类
public class OrderServerTest {
@Inject private OrderService orderService;
@Before
public void SetUp() {
//利用injectMembers,将当前所需的类具现化
Guice.createInjector(new ServerModule()).injectMembers(this);;
}
@Test
public void testSendToPayment() {
// 旧方法,将所需的类具现化
// OrderService orderService = Guice.createInjector(new ServerModule())
// .getInstance(OrderService.class);
orderService.sendToPayment(789L);
}
}
github: guice系列的测试类都在