AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
主要用在公共业务上,例如:
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4' 复制代码
apply plugin: 'android-aspectjx' 复制代码
api 'org.aspectj:aspectjrt:1.8.9' 复制代码
@Target({ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface ClickLimit { int value() default 500; } 复制代码
@Aspect public class ClickLimitAspect { private static final int CHECK_FOR_DEFAULT_TIME = 500; private static final String POINTCUT_ON_ANNOTATION = "execution(@com.xuetian.xtuikit.click.annotation.ClickLimit * *(..))"; @Pointcut(POINTCUT_ON_ANNOTATION) public void onAnnotationClick(){} @Around("onAnnotationClick()") public void processJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable { try { Signature signature = joinPoint.getSignature(); if (!(signature instanceof MethodSignature)){ joinPoint.proceed(); return; } MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); boolean isHasLimitAnnotation = method.isAnnotationPresent(ClickLimit.class); String methodName = method.getName(); int intervalTime = CHECK_FOR_DEFAULT_TIME; if (isHasLimitAnnotation){ ClickLimit clickLimit = method.getAnnotation(ClickLimit.class); int limitTime = clickLimit.value(); if (limitTime <= 0){ joinPoint.proceed(); return; } intervalTime = limitTime; } Object[] args = joinPoint.getArgs(); View view = getViewFromArgs(args); if (view == null) { joinPoint.proceed(); return; } Object viewTimeTag = view.getTag(R.integer.xt_click_limit_tag_view); if (viewTimeTag == null){ proceedAnSetTimeTag(joinPoint, view); return; } long lastClickTime = (long) viewTimeTag; if (lastClickTime <= 0){ proceedAnSetTimeTag(joinPoint, view); return; } if (!canClick(lastClickTime, intervalTime)){ return; } proceedAnSetTimeTag(joinPoint, view); } catch (Throwable e) { e.printStackTrace(); joinPoint.proceed(); } } public void proceedAnSetTimeTag(ProceedingJoinPoint joinPoint, View view) throws Throwable { view.setTag(R.integer.xt_click_limit_tag_view, System.currentTimeMillis()); joinPoint.proceed(); } public View getViewFromArgs(Object[] args) { if (args != null && args.length > 0) { Object arg = args[0]; if (arg instanceof View) { return (View) arg; } } return null; } public boolean canClick(long lastClickTime, int intervalTime) { long currentTime = System.currentTimeMillis(); long realIntervalTime = currentTime - lastClickTime; return realIntervalTime >= intervalTime; } } 复制代码