java动态代理实现数据库事务拦截器
很多开源框架中都实现了拦截器功能,比如Spring、WebWork、Struts2等。例用拦截器,可以在对类方法进行调用的前后加入共通的操作,比如在调用方法的前后打印log等,使业务代码更加单纯。
拦截器是利用java的动态代理技术来实现的。接下来我们就看一个例子,这个例子利用java动态代理,对所有insert、update、delete为前缀的方法进行事务处理。
- /**
- * grape mxjava.com.grape.core.interceptor.Interceptor.java 2008-6-15
- */
- package mxjava.com.grape.core.interceptor;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Proxy;
- /**
- * 拦截器
- *
- * @author hiswing
- */
- public abstract class Interceptor implements InvocationHandler {
- /** 被拦截的对象 */
- protected Object obj;
- /**
- * 动态生成一个代理类对象
- * @param obj
- * @return 代理类对象
- */
- public Object bind(Object obj) {
- this.obj = obj;
- Class cls = this.obj.getClass();
- // 被代理类的ClassLoader
- // 要被代理的接口,本方法返回对象会自动声称实现了这些接口
- return Proxy.newProxyInstance(cls.getClassLoader(),
- cls.getInterfaces(), this);
- }
- }
- /**
- * grape mxjava.com.grape.core.interceptor.TransactionDynamicProxy.java
- * 2008-6-15
- */
- package mxjava.com.grape.core.interceptor;
- import java.lang.reflect.Method;
- import mxjava.com.grape.core.AppContext;
- import mxjava.com.grape.core.db.Connection;
- import mxjava.com.grape.core.db.DBException;
- /**
- * 数据库事务拦截器
- * @author hiswing
- */
- public class TransactionInterceptor extends Interceptor {
- /** 数据库链接 */
- private Connection connect;
- private String[] method;
- /**
- * 初期化数据库链接
- */
- public TransactionInterceptor() {
- this.connect = getConnection();
- this.method = new String[] {"insert", "update", "delete"};
- }
- /**
- * 代理要调用的方法,并在方法调用前后调用连接器的方法
- *
- * @param proxy 代理对象
- * @param method 被代理的接口方法
- * @param args 被代理接口方法的参数
- * @return 方法调用返回的结果
- * @throws Throwable
- */
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- Object result = null;
- boolean flag = this.checkName(method.getName());
- try {
- if (flag) {
- this.connect.begin();
- result = method.invoke(super.obj, args);
- this.connect.commit();
- } else {
- result = method.invoke(super.obj, args);
- }
- } catch (DBException ex) {
- if (flag) {
- this.connect.rollBack();
- }
- throw ex;
- }
- return result;
- }
- /**
- * 检查是否需要进行事务处理
- * @param methodName
- * @return
- */
- private boolean checkName(String methodName) {
- if (this.method == null || this.method.length == 0) {
- return false;
- }
- for (String mn : this.method) {
- if (!"".equals(mn.trim()) && methodName.indexOf(mn) == 0) {
- return true;
- }
- }
- return false;
- }
- }


















