利用上文业务,插入一个缓存类来说明作用域
/**
* 实现cache,使用谷歌类库
*
* @author lg
*
*/
public class GuiceDemoCache extends AbstractCache {
private final Map keyValues = new HashMap<>();
@Override
public String getIfPresent(Object key) {
return keyValues.get(key);
}
@Override
public void put(String key, String value) {
keyValues.put(key, value);
}
}
paymentServiceImpl部分代码:
public class PaymentServiceImpl implements PaymentService {
private final Cache cache;
@Inject
private PaymentServiceImpl(Cache cache) {
this.cache = cache;
}
void putCache(String key, String value) {//同一个包下可用
cache.put(key, value);
}
PriceServiceImpl部分代码
private PrinceServiceImpl implements PrinceService{
private final Cache cache;
@Inject
public PriceServiceImpl(Set supportedCurrenties,
Cache cache) {
this.supportedCurrenties = supportedCurrenties;
this.cache = cache;
}
String getCache(String key) {
return cache.getIfPresent(key);// 如果存在获取
}
测试类:
public class CacheTests {
//由于没有实现接口,是写于类内部,故注入实现类
@Inject private PaymentServiceImpl paymentServiceImpl;
@Inject private PriceServiceImpl priceServiceImpl;
@Before public void setUp() {
Guice.createInjector(new ServerModule())
.injectMembers(this);
}
@Test
public void test() {
paymentServiceImpl.putCache("Test","hahah");
String cache = priceServiceImpl.getCache("Test");
Assert.assertEquals(cache, "hahah");
}
}
得出的结果是,他们的作用域仅局限于其方法内,每次获取仍需获取新的cache。
要使其全局唯一,
(1)@Singleton注解,javax.inject.Singleton;下;
(2)bind(new TypeLiteral
.to(GuiceDemoCache.class).in(Singleton.class);;
(3)@Provides @Singleton Cache
return new GuiceDemoCache();
}
但是对于多线程而言,这样的单例并不能满足我们需要,因为缓存用的是HashMap,改成ConcurrentHashMap即可;
AOP: Aspect Oriented Programming
Aspect: 一般针对日志,安全(全局拦截)、Transaction.....
Guice有一个Methodinterceptor 接口:
将方法拦截下来,来做Aspect所要做的事情,拦截下来后:
(1)可以获得各种信息; 函数调用类、方法、参数。。。。
(2)控制是否函数调用; 比如是否拥有权限访问。。。
eg:
OrderServerImpl.class中定义一个注解,仅需运行时即可
@Override @Logged
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);
}
ServerModule.class
bindInterceptor(Matchers.any(), //所有类别
Matchers.annotatedWith(Logged.class),//注释为Logged的方法
new MethodInterceptor() {//拦截处理
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
System.out.println(String.format("calling %s#%s(%s)",
method.getDeclaringClass().getName(),
method.getName(),
Joiner.on(",").join(
invocation.getArguments())));
return invocation.proceed();
}
});
调用测试类:
calling CoffeeAndIce.GuiceDemo.server.impl.OrderServerImpl#sendToPayment(789) //日志打印成功
tips: requestInjection(instance);//可以用来要求注入某个类
1、绑定Methodinterceptor
2、实现Methodinterceptor
3、在Methodinterceptor 中注入Dependency
warm:但是guice的Aop必须使用在通过guice创建的对象上,比如我们手工创建一个对象,添加日志AOP,这时,guice也是没有办法去拦截的,必须通过guice从头开始inject开始的才可以进行AOP处理