spring aop介绍
spring提供了五种通知类型
- Interception Around JointPoint前后调用,实现此类需要实现接口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 transation insert success! docommit 方法返回值 : true ==================================== 开始执行insert2方法 begin transation rollback transaction Exception 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 more Caused by: java.lang.ArithmeticException: / by zero at com.july.testspring.transaction.StudentServiceImpl.insert2(StudentServiceImpl.java:13) ... 10 more
作者:飞天小贼
链接:http://www.jianshu.com/p/11c1a39c7e8e
來源:简书
Java JDK动态代理实现自己的事务管理器
最新推荐文章于 2024-08-08 15:53:37 发布