diff --git a/mars-core/pom.xml b/mars-core/pom.xml index b20e765..6b112d4 100644 --- a/mars-core/pom.xml +++ b/mars-core/pom.xml @@ -5,7 +5,7 @@ com.github.yuyenews Mars - 3.0.6 + 3.0.7 mars-core diff --git a/mars-core/src/main/java/com/mars/aop/proxy/MarsBeanProxy.java b/mars-core/src/main/java/com/mars/aop/proxy/MarsBeanProxy.java index f229242..23a8373 100644 --- a/mars-core/src/main/java/com/mars/aop/proxy/MarsBeanProxy.java +++ b/mars-core/src/main/java/com/mars/aop/proxy/MarsBeanProxy.java @@ -2,11 +2,12 @@ package com.mars.aop.proxy; import java.lang.reflect.Method; +import com.mars.aop.proxy.exec.ExecAop; +import com.mars.aop.proxy.exec.ExecRedisLock; import com.mars.core.annotation.MarsAop; +import com.mars.core.annotation.RedisLock; import com.mars.core.annotation.Traction; -import com.mars.aop.constant.AopConstant; import com.mars.core.model.AopModel; -import com.mars.core.ncfg.traction.TractionClass; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; @@ -46,16 +47,17 @@ public class MarsBeanProxy implements MethodInterceptor { public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object obj = null; Class c = null; - + RedisLock redisLock = null; try { MarsAop marsAop = method.getAnnotation(MarsAop.class); Traction traction = method.getAnnotation(Traction.class); + redisLock = method.getAnnotation(RedisLock.class); /* 校验同一个方法上不能同时存在aop和traction注解 */ - checkAnnot(marsAop,traction,method); + ExecAop.checkAnnot(marsAop,traction,method,cls); - AopModel aopModel = getAopModel(marsAop,traction); + AopModel aopModel = ExecAop.getAopModel(marsAop,traction); if (aopModel != null) { c = aopModel.getCls(); } @@ -63,102 +65,27 @@ public class MarsBeanProxy implements MethodInterceptor { obj = c.getDeclaredConstructor().newInstance(); } - startMethod(c, obj, args, aopModel); + /* 加分布式锁 */ + Boolean hasLock = ExecRedisLock.lock(redisLock); + if(!hasLock){ + return null; + } + + /* 执行aop的开始方法 */ + ExecAop.startMethod(c, obj, args, aopModel); + + /* 执行方法本体 */ Object o1 = methodProxy.invokeSuper(o, args); - endMethod(c, obj, args,o1); + + /* 执行aop的结束方法 */ + ExecAop.endMethod(c, obj, args,o1); return o1; } catch (Throwable e) { - exp(c, obj, e); + ExecAop.exp(c, obj, e); throw e; + } finally { + /* 解分布式锁 */ + ExecRedisLock.unlock(redisLock); } } - - /** - * 方法开始前 - * @param c 类 - * @param obj 对象 - * @param args 参数 - * @param aopModel Aop实体 - * @throws Exception 异常 - */ - private void startMethod(Class c, Object obj, Object[] args, AopModel aopModel) throws Exception { - if (c == null) { - return; - } - if (c.getName().equals(TractionClass.getCls().getName())) { - Method m2 = c.getDeclaredMethod(AopConstant.START_METHOD, new Class[]{Object[].class, AopModel.class}); - m2.invoke(obj, new Object[]{args, aopModel}); - } else { - Method m2 = c.getDeclaredMethod(AopConstant.START_METHOD, new Class[]{Object[].class}); - m2.invoke(obj, new Object[]{args}); - } - } - - /** - * 方法开始后 - * @param c 类 - * @param obj 对象 - * @param args 参数 - * @throws Exception 异常 - */ - private void endMethod(Class c, Object obj, Object[] args, Object result) throws Exception { - if (c == null) { - return; - } - if (c.getName().equals(TractionClass.getCls().getName())) { - Method m2 = c.getDeclaredMethod(AopConstant.END_METHOD, new Class[]{Object[].class}); - m2.invoke(obj, new Object[]{args}); - } else { - Method m2 = c.getDeclaredMethod(AopConstant.END_METHOD, new Class[]{Object[].class, Object.class}); - m2.invoke(obj, new Object[]{args,result}); - } - } - - /** - * 异常 - * @param c 类 - * @param obj 对象 - * @param e 异常对象 - * @throws Exception 异常 - */ - private void exp(Class c, Object obj, Throwable e) throws Exception { - if (c == null) { - return; - } - Method m4 = c.getDeclaredMethod(AopConstant.EXP_METHOD, new Class[]{Throwable.class}); - m4.invoke(obj, new Object[]{e}); - } - - /** - * 校验注解是否符合规则 - * @param marsAop aop注解 - * @param traction 事务监听注解 - * @param method 被监听的方法 - * @throws Exception 异常 - */ - private void checkAnnot(MarsAop marsAop,Traction traction,Method method) throws Exception { - if(marsAop != null && traction != null) { - throw new Exception(cls.getName()+"类中的["+method.getName()+"]方法同时存在MarsAop和Traction注解"); - } - } - - /** - * 获取aop实体 - * @param marsAop aop注解 - * @param traction 事务监听注解 - * @return aop实体 - */ - private AopModel getAopModel(MarsAop marsAop,Traction traction){ - AopModel aopModel = null; - if(marsAop != null) { - aopModel = new AopModel(); - aopModel.setCls(marsAop.className()); - } else if(traction != null) { - aopModel = new AopModel(); - aopModel.setCls(TractionClass.getCls()); - aopModel.setTractionLevel(traction.level()); - aopModel.setExecutorType(traction.executorType()); - } - return aopModel; - } } diff --git a/mars-core/src/main/java/com/mars/aop/proxy/exec/ExecAop.java b/mars-core/src/main/java/com/mars/aop/proxy/exec/ExecAop.java new file mode 100644 index 0000000..5bfd771 --- /dev/null +++ b/mars-core/src/main/java/com/mars/aop/proxy/exec/ExecAop.java @@ -0,0 +1,104 @@ +package com.mars.aop.proxy.exec; + +import com.mars.aop.constant.AopConstant; +import com.mars.core.annotation.MarsAop; +import com.mars.core.annotation.Traction; +import com.mars.core.model.AopModel; +import com.mars.core.ncfg.traction.TractionClass; + +import java.lang.reflect.Method; + +/** + * 执行AOP + */ +public class ExecAop { + + /** + * 方法开始前 + * @param c 类 + * @param obj 对象 + * @param args 参数 + * @param aopModel Aop实体 + * @throws Exception 异常 + */ + public static void startMethod(Class c, Object obj, Object[] args, AopModel aopModel) throws Exception { + if (c == null) { + return; + } + if (c.getName().equals(TractionClass.getCls().getName())) { + Method m2 = c.getDeclaredMethod(AopConstant.START_METHOD, new Class[]{Object[].class, AopModel.class}); + m2.invoke(obj, new Object[]{args, aopModel}); + } else { + Method m2 = c.getDeclaredMethod(AopConstant.START_METHOD, new Class[]{Object[].class}); + m2.invoke(obj, new Object[]{args}); + } + } + + /** + * 方法开始后 + * @param c 类 + * @param obj 对象 + * @param args 参数 + * @throws Exception 异常 + */ + public static void endMethod(Class c, Object obj, Object[] args, Object result) throws Exception { + if (c == null) { + return; + } + if (c.getName().equals(TractionClass.getCls().getName())) { + Method m2 = c.getDeclaredMethod(AopConstant.END_METHOD, new Class[]{Object[].class}); + m2.invoke(obj, new Object[]{args}); + } else { + Method m2 = c.getDeclaredMethod(AopConstant.END_METHOD, new Class[]{Object[].class, Object.class}); + m2.invoke(obj, new Object[]{args,result}); + } + } + + /** + * 异常 + * @param c 类 + * @param obj 对象 + * @param e 异常对象 + * @throws Exception 异常 + */ + public static void exp(Class c, Object obj, Throwable e) throws Exception { + if (c == null) { + return; + } + Method m4 = c.getDeclaredMethod(AopConstant.EXP_METHOD, new Class[]{Throwable.class}); + m4.invoke(obj, new Object[]{e}); + } + + /** + * 校验注解是否符合规则 + * @param marsAop aop注解 + * @param traction 事务监听注解 + * @param method 被监听的方法 + * @throws Exception 异常 + */ + public static void checkAnnot(MarsAop marsAop, Traction traction, Method method,Class cls) throws Exception { + if(marsAop != null && traction != null) { + throw new Exception(cls.getName()+"类中的["+method.getName()+"]方法同时存在MarsAop和Traction注解"); + } + } + + /** + * 获取aop实体 + * @param marsAop aop注解 + * @param traction 事务监听注解 + * @return aop实体 + */ + public static AopModel getAopModel(MarsAop marsAop,Traction traction){ + AopModel aopModel = null; + if(marsAop != null) { + aopModel = new AopModel(); + aopModel.setCls(marsAop.className()); + } else if(traction != null) { + aopModel = new AopModel(); + aopModel.setCls(TractionClass.getCls()); + aopModel.setTractionLevel(traction.level()); + aopModel.setExecutorType(traction.executorType()); + } + return aopModel; + } +} diff --git a/mars-core/src/main/java/com/mars/aop/proxy/exec/ExecRedisLock.java b/mars-core/src/main/java/com/mars/aop/proxy/exec/ExecRedisLock.java new file mode 100644 index 0000000..2c88cef --- /dev/null +++ b/mars-core/src/main/java/com/mars/aop/proxy/exec/ExecRedisLock.java @@ -0,0 +1,101 @@ +package com.mars.aop.proxy.exec; + +import com.mars.core.annotation.RedisLock; +import com.mars.ioc.factory.BeanFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Method; + +/** + * 执行redis分布式锁 + * + * 通过调用redis模块的MarsRedisLock类里面的方法,进行加解锁操作 + */ +public class ExecRedisLock { + + private static Logger logger = LoggerFactory.getLogger(ExecRedisLock.class); + + /** + * 分布式锁的class对象 + */ + private static Class redisLockClass; + + /** + * 分布式锁的实例 + */ + private static Object redisLockObj; + + /** + * 加锁 + * @param redisLock 注解 + * @return 加锁结果 + * @throws Exception 异常 + */ + public static Boolean lock(RedisLock redisLock) { + return exec(redisLock,"lock"); + } + + /** + * 解锁 + * @param redisLock 注解 + * @return 解锁结果 + * @throws Exception 异常 + */ + public static Boolean unlock(RedisLock redisLock) { + return exec(redisLock,"unlock"); + } + + /** + * 执行加解锁操作 + * @param redisLock 注解 + * @param methodName 执行的方法 + * @return 结果 + * @throws Exception 异常 + */ + private static Boolean exec(RedisLock redisLock,String methodName) { + try { + if(redisLock == null){ + /* 这个true代表不需要加解锁,为了让程序继续往下走 */ + return true; + } + redisLockClass = getRedisLockClass(); + redisLockObj = getRedisLockObj(); + Method method = redisLockClass.getMethod(methodName,new Class[]{String.class}); + Object result = method.invoke(redisLockObj,new Object[]{redisLock.key()}); + if(result == null){ + return false; + } + return Boolean.parseBoolean(result.toString()); + } catch (Exception e){ + logger.error("分布式锁出现异常["+methodName+"]",e); + return false; + } + } + + /** + * 获取分布式锁的class对象 + * @return 分布式锁的class对象 + * @throws Exception 异常 + */ + private static Class getRedisLockClass() throws Exception { + /* 这里只是为了节约性能,在首次并发的情况下,即使执行了多次,也不会存在安全问题 */ + if(redisLockClass == null) { + redisLockClass = Class.forName("com.mars.redis.lock.MarsRedisLock"); + } + return redisLockClass; + } + + /** + * 获取分布式锁的实例对象 + * @return 分布式锁的实例对象 + * @throws Exception 异常 + */ + private static Object getRedisLockObj() throws Exception { + /* 这里只是为了节约性能,在首次并发的情况下,即使执行了多次,也不会存在安全问题 */ + if(redisLockObj == null) { + redisLockObj = BeanFactory.getBean("marsRedisLock",Object.class); + } + return redisLockObj; + } +} diff --git a/mars-core/src/main/java/com/mars/core/annotation/RedisLock.java b/mars-core/src/main/java/com/mars/core/annotation/RedisLock.java new file mode 100644 index 0000000..9c1d0b7 --- /dev/null +++ b/mars-core/src/main/java/com/mars/core/annotation/RedisLock.java @@ -0,0 +1,11 @@ +package com.mars.core.annotation; + +import java.lang.annotation.*; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RedisLock { + + String key(); +} diff --git a/mars-jdbc/pom.xml b/mars-jdbc/pom.xml index ab59b2b..6a707eb 100644 --- a/mars-jdbc/pom.xml +++ b/mars-jdbc/pom.xml @@ -5,7 +5,7 @@ Mars com.github.yuyenews - 3.0.6 + 3.0.7 4.0.0 mars-jdbc diff --git a/mars-mvc/pom.xml b/mars-mvc/pom.xml index 1638472..a3b105d 100644 --- a/mars-mvc/pom.xml +++ b/mars-mvc/pom.xml @@ -5,7 +5,7 @@ com.github.yuyenews Mars - 3.0.6 + 3.0.7 mars-mvc diff --git a/mars-netty/pom.xml b/mars-netty/pom.xml index 18f257d..792d1ad 100644 --- a/mars-netty/pom.xml +++ b/mars-netty/pom.xml @@ -5,7 +5,7 @@ com.github.yuyenews Mars - 3.0.6 + 3.0.7 mars-netty diff --git a/mars-redis/pom.xml b/mars-redis/pom.xml index 9e13b6c..7bb1b1a 100644 --- a/mars-redis/pom.xml +++ b/mars-redis/pom.xml @@ -5,7 +5,7 @@ Mars com.github.yuyenews - 3.0.6 + 3.0.7 4.0.0 diff --git a/mars-server/pom.xml b/mars-server/pom.xml index 414da2c..cf3f0d6 100644 --- a/mars-server/pom.xml +++ b/mars-server/pom.xml @@ -5,7 +5,7 @@ com.github.yuyenews Mars - 3.0.6 + 3.0.7 mars-server diff --git a/pom.xml b/pom.xml index 50b7f63..52653cf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.yuyenews Mars - 3.0.6 + 3.0.7 pom mars-core