Java JDK动态代理实现自己的事务管理器

来源:互联网 发布:淘宝设计美工招聘 编辑:程序博客网 时间:2024/06/09 02:06

spring aop介绍

spring提供了五种通知类型
  • Interception AroundJointPoint前后调用,实现此类需要实现接口MethodInterceptor。
  • Before通知需要实现接口MethodBeforeAdvice。
  • After Returning 通知需要实现接口AfterReturningAdvice。
  • Throw通知需要实现接口ThrowsAdvice
  • Introduction通知需要实现接口IntroductionAdvisor和IntroductionInterceptor。

怎样实现自己的事务管理器

  • 定义业务service接口
package com.july.testspring.transaction;public interface StudentService {    public boolean insert(StudentDemo demo);    public boolean insert2(StudentDemo studentDemo);}
  • 定义DO类
package com.july.testspring.transaction;import java.io.Serializable;public class StudentDemo implements Serializable {    /**     *      */    private static final long serialVersionUID = 1L;    private int id;        private String name;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String toString() {        return "StudentDemo [id=" + id + ", name=" + name + "]";    }    }
  • 业务service接口实现
package com.july.testspring.transaction;public class StudentServiceImpl implements StudentService {    @Override    public boolean insert(StudentDemo demo) {        System.out.println("insert success!");        return true;    }    @Override    public boolean insert2(StudentDemo studentDemo) {        System.out.println(1/0);        return false;    }}
  • 定义Advice通知类
package com.july.testspring.transaction;import java.lang.reflect.Method;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;import org.springframework.util.StringUtils;public class MyTransactionInterceptor implements MethodInterceptor {        final ThreadLocal<TransactionInfo> transactionThread = new ThreadLocal<TransactionInfo>();    @Override    public Object invoke(MethodInvocation methodInvocation) throws Throwable {                        Class targetClass = (methodInvocation.getThis() != null) ? methodInvocation.getThis().getClass() : null;        //        if(methodInvocation.getMethod().getName().equals("toString")) {            return "";        }                //begin Transaction        TransactionInfo txInfo = createTransactionIfNecessary(methodInvocation.getMethod(), methodInvocation);        Object retVal = null;        try {            retVal = methodInvocation.proceed();        }catch (Throwable e) {            //回滚相关事务  父类或子类实现            doCloseTransactionAfterThrowing(geTransactionInfo(), e);            throw e;        } finally {            //设置transaction 状态            TransactionInfo info = geTransactionInfo();            info.setSuccessStatus(StatusType.SUCCESS);            doFinally(info);        }        //commit        doCommitTransactionAfterReturning(geTransactionInfo());        return retVal;    }            private void doFinally(TransactionInfo transactionInfo) {        setTransactionInfo(transactionInfo);    }    private void doCommitTransactionAfterReturning(com.july.testspring.transaction.TransactionInfo geTransactionInfo) {        System.out.println("docommit");    }    private void doCloseTransactionAfterThrowing(com.july.testspring.transaction.TransactionInfo geTransactionInfo,            Throwable e) {        System.out.println("rollback transaction");            }    private com.july.testspring.transaction.TransactionInfo createTransactionIfNecessary(Method method,            MethodInvocation methodInvocation) {        System.out.println("begin transation");        TransactionInfo transactionInfo = new TransactionInfo();        setTransactionInfo(transactionInfo);        return transactionInfo;    }    public TransactionInfo geTransactionInfo() {        return transactionThread.get();    }        public void setTransactionInfo(TransactionInfo transactionInfo) {        transactionThread.set(transactionInfo);    }}
  • JDK动态代理InvocationHandler,实现InvocationHandler接口。
import java.lang.reflect.Array;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Arrays;import org.aopalliance.aop.Advice;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;import org.springframework.aop.Advisor;import org.springframework.aop.framework.Advised;public class ProxyFactory implements InvocationHandler {        public Object target;        Advice advisor = (Advice) new MyTransactionInterceptor();        public ProxyFactory(Object target) {        this.target = target;    }                /*private static class ProxyFactoryClient {        private static final ProxyFactory PROXY_FACTORY = new ProxyFactory();    }*/        /**     * 创建代理     *      * @param classzz     * @return     */    public <T> T createProxy(Class<?> target) {        return (T) Proxy.newProxyInstance(getClassLoader(),getMethodInterceptor(target), this);    }    private Class[] getMethodInterceptor(Class<?> target) {        return target.getInterfaces();    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        MethodInvocation methodInvocation = new TransactionMethodInvocation(args, target, method, this.advisor);        return methodInvocation.proceed();    }                private ClassLoader getClassLoader() {        return Thread.currentThread().getContextClassLoader();    }    }
  • 实现MethodInvocation接口 TransactionMethodInvocation
package com.july.testspring.transaction;import java.lang.reflect.AccessibleObject;import java.lang.reflect.Method;import java.util.List;import org.aopalliance.aop.Advice;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;import org.springframework.aop.Advisor;public class TransactionMethodInvocation implements MethodInvocation{        protected Object[] arguments;        protected final Object target;    protected final Method method;        Advice interceptorsAndDynamicMethodMatchers;        private int currentInterceptorIndex = -1;    public TransactionMethodInvocation(Object[] arguments,Object target,Method method,Advice interceptorsAndDynamicMethodMatchers) {        this.arguments = arguments;        this.target = target;        this.method = method;        this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;    }        @Override    public Object[] getArguments() {        return this.arguments;    }    @Override    public AccessibleObject getStaticPart() {        return this.method;    }    @Override    public Object getThis() {        return this.target;    }    @Override    public Object proceed() throws Throwable {        if(++currentInterceptorIndex == 1) {             return this.method.invoke(this.target, this.arguments);        }        return ((MethodInterceptor) interceptorsAndDynamicMethodMatchers).invoke(this);    }    @Override    public Method getMethod() {        return this.method;    }}
  • 定义TransactionInfo 事务相关信息
import java.util.concurrent.atomic.AtomicLong;public class TransactionInfo {    //1 成功  0 失败    private volatile int status = 0;        private final AtomicLong atomicLong = new AtomicLong();        public void setSuccessStatus(StatusType type) {        if(type.getCode() != status) {            atomicLong.compareAndSet(0, type.getCode());        }    }        public void setFailStatus(StatusType type) {        if(type.getCode() != status) {            atomicLong.compareAndSet(1, type.getCode());        }    }}
  • 测试类
import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.july.testspring.service.UserService;import com.july.testspring.service.impl.UserServiceImpl;public class Test {        public static void main(String[] args) {        StudentService userService2 = new ProxyFactory(new StudentServiceImpl()).createProxy(StudentServiceImpl.class);        System.out.println("开始执行insert方法");        System.out.println("方法返回值 : " + userService2.insert(new StudentDemo()));                System.out.println("====================================");                System.out.println("开始执行insert2方法");        System.out.println(userService2.insert2(new StudentDemo()));    }}
  • 运行结果
begin transationinsert success!docommit方法返回值 : true====================================开始执行insert2方法begin transationrollback transactionException in thread "main" java.lang.reflect.UndeclaredThrowableException    at com.sun.proxy.$Proxy0.insert2(Unknown Source)    at com.july.testspring.transaction.Test.main(Test.java:26)Caused by: java.lang.reflect.InvocationTargetException    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)    at java.lang.reflect.Method.invoke(Method.java:498)    at com.july.testspring.transaction.TransactionMethodInvocation.proceed(TransactionMethodInvocation.java:49)    at com.july.testspring.transaction.MyTransactionInterceptor.invoke(MyTransactionInterceptor.java:26)    at com.july.testspring.transaction.TransactionMethodInvocation.proceed(TransactionMethodInvocation.java:51)    at com.july.testspring.transaction.ProxyFactory.invoke(ProxyFactory.java:51)    ... 2 moreCaused by: java.lang.ArithmeticException: / by zero    at com.july.testspring.transaction.StudentServiceImpl.insert2(StudentServiceImpl.java:13)    ... 10 more


作者:飞天小贼
链接:http://www.jianshu.com/p/11c1a39c7e8e
來源:简书
阅读全文
1 0