类似于Spring的声明式事务管理,Guice中也可以很容易的实现,这里我拿Guice+Ibatis举个例子。
1. Guice要支持aop,首先我们引入aopalliance.jar。
2. 声明自己的事务annotation
package com.yingxia.server.common;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Transaction {
}
3. 声明切面事务拦截器TransactionInterceptor
package com.yingxia.server.common;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class TransactionInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object obj = null;
try {
BaseDao.sqlMapper.startTransaction();
System.out.println("事务开始");
obj = mi.proceed();
BaseDao.sqlMapper.commitTransaction();
System.out.println("事务提交");
} finally {
BaseDao.sqlMapper.endTransaction();
System.out.println("事务结束");
}
return obj;
}
}
4. 最后把拦截器绑定到Guice全局的Injector当中。这里请注意静态引入import static。bindInterceptor方法的前两个参数一个是用来过滤类,一个用来过滤方法。好了,这样你所有GuiceRemoteServiceServlet类的子类的带有Transaction标注的方法都将被纳入事务管理了。
private static final Injector injector = Guice.createInjector(new Module() {
@Override
public void configure(Binder binder) {
binder.bindInterceptor(
subclassesOf(GuiceRemoteServiceServlet.class),
any(),
new ExceptionInterceptor()
);
binder.bindInterceptor(
subclassesOf(GuiceRemoteServiceServlet.class),
annotatedWith(Transaction.class),
new TransactionInterceptor()
);
}
});