Android里使用AspectJ实现AOP
Aspectj提供一种在字符串里编程的模式,即在字符串里写函数,然后程序启动的时候会动态的把字符串里的函数给执行了。
例如:
"execution(* *(..))"
这里的execution就是一个函数,我们调用它,然后传递的参数是【* *(..)】。
execution: 用于匹配方法执行的连接点;
execution(public * *(..)) ==> 匹配所有目标类的public方法,第一个*代表返回类型,第二个*代表方法名,而..代表任意入参的方法。
execution(* com.oysept.springboot.controller..*.*(..)) ==> 该包及所有子包下任何类的任何方法。
execution(* com.oysept.springboot.controller.*(..)) ==> 该包下任何类的任何方法。
execution(* com.oysept.springboot.controller.AspectJController.*(..)) ==> 该包下AspectJController类的任何方法。
execution(* com..*.*Controller.method*(..)) ==> 匹配包名前缀为com的任何包下类名后缀为Controller的方法,方法名必须以method为前缀。
execution(* *To(..)) ==> 匹配目标类所有以To为后缀的方法。
注: 该方法只是为了声明一个公共的环绕通知,也可以直接在具体方法配置,如: @Around("execution(* com.oysept.springboot.controller..*.*(..))")
@Before和@AfterReturning
/**
* @Before:定义了前置通知方法。打印出入参
* @AfterReturning:定义了后置返回通知方法。打印出入参、返参
*/
@Slf4j
@Aspect
@Component
public class AopAspect_Basic {
@Before("execution(public * com.k.tender.controller.business.user.UserController.*(..))")
public void doBefore(JoinPoint point){
String methodName = point.getSignature().getName();
List<Object> args = Arrays.asList(point.getArgs());
log.info("调用前连接点方法为:" + methodName + ",参数为:" + args);
} @AfterReturning(value = "execution(public * com.k.tender.controller.business.user.UserController.*(..))", returning = "returnValue")
public void doAfterReturning(JoinPoint point, Object returnValue){
String methodName = point.getSignature().getName();
List<Object> args = Arrays.asList(point.getArgs());
log.info("调用前连接点方法为:" + methodName + ",参数为:" + args + ",返回值为:" + returnValue);
} }
如上代码,我们使用了@Before和@AfterReturning注解,在UserController调用前和后,分别埋了点,并输出了函数的入参和出参。
@Pointcut
@Pointcut("execution(public * com.k.tender.controller.business.tender.TenderController.*(..))")
public void doPointCut() {
}
@Before("doPointCut()")
public void doBefore(JoinPoint point){
String methodName = point.getSignature().getName();
List<Object> args = Arrays.asList(point.getArgs());
log.info("调用前连接点方法为:" + methodName + ",参数为:" + args);
}
@AfterReturning(value = "doPointCut()", returning = "returnValue")
public void doAfterReturning(JoinPoint point, Object returnValue){
String methodName = point.getSignature().getName();
List<Object> args = Arrays.asList(point.getArgs());
log.info("调用前连接点方法为:" + methodName + ",参数为:" + args + ",返回值为:" + returnValue);
}
对注解埋点
有时候,我们希望编写一个注解,然后让有该注解的函数,都被拦截,那么就可以使用Aspectj的注解埋点模式。
代码如下:
@Slf4j
@Aspect
@Component
public class AopAspect_Annotation { @Before("@annotation(com.k.tender.aop.MyAop)")
public void doBefore(JoinPoint point){
String methodName = point.getSignature().getName();
List<Object> args = Arrays.asList(point.getArgs());
log.info("调用前连接点方法为:" + methodName + ",参数为:" + args);
}
@AfterReturning(value ="@annotation(com.k.tender.aop.MyAop)", returning = "returnValue")
public void doAfterReturning(JoinPoint point, Object returnValue){
String methodName = point.getSignature().getName();
List<Object> args = Arrays.asList(point.getArgs());
log.info("调用前连接点方法为:" + methodName + ",参数为:" + args + ",返回值为:" + returnValue);
}
}
String value() default "自定义注解拦截";
}
如果觉得写注解的命名空间麻烦,也可以这样写:
@Before("@annotation(apiOperation)")
public void doBefore(JoinPoint point, MyAopAsyncTask apiOperation) {
String methodName = point.getSignature().getName();
List<Object> args = Arrays.asList(point.getArgs());
log.info("调用前连接点方法为:" + methodName + ",参数为:" + args);
}
还可以将注解和前面的excution函数结合写:
@Before("execution(public * com.k..*.*(..)) && @annotation(apiOperation)")
public void doBefore(JoinPoint point, MyAopAsyncTask apiOperation) throws NoSuchMethodException {
String methodName = point.getSignature().getName();
List<Object> args = Arrays.asList(point.getArgs());
log.info("调用前连接点方法为:" + methodName + ",参数为:" + args);
}
有时候我们的拦截会触发多次,这个具体原因调查起来很麻烦,我们也可以这样解决,代码如下:
private volatile long hashcode = 0;//应对重复触发
@Before("execution(public * com.k..*.*(..)) && @annotation(apiOperation)") public void doBefore(JoinPoint point, MyAopAsyncTask apiOperation) throws NoSuchMethodException {
if (hashcode != point.getTarget().hashCode()) {
log.info("========doBefore========");
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
String method = request.getMethod(); } }
使用hashcode来过滤多次拦截。
----------------------------------------------------------------------------------------------------
到此,Android里使用AspectJ实现AOP就介绍完了。
----------------------------------------------------------------------------------------------------
注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!
https://www.cnblogs.com/kiba/p/18027435

Android里使用AspectJ实现AOP的更多相关文章
- Spring @AspectJ 实现AOP 入门例子(转)
AOP的作用这里就不再作说明了,下面开始讲解一个很简单的入门级例子. 引用一个猴子偷桃,守护者守护果园抓住猴子的小情节. 1.猴子偷桃类(普通类): package com.samter.common ...
- (转)Spring使用AspectJ进行AOP的开发:注解方式
http://blog.csdn.net/yerenyuan_pku/article/details/69790950 Spring使用AspectJ进行AOP的开发:注解方式 之前我已讲过Sprin ...
- AspectJ对AOP的实现
一:你应该明白的知识 1.对于AOP这种编程思想,很多框架都进行了实现.Spring就是其中之一,可以完成面向切面编程.然而,AspectJ也实现了AOP的功能,且实现方式更为简捷,使用更加方便,而且 ...
- 注意Android里TextView控件的一个小坑,用android:theme来设置样式时动态载入的layout会丢失该样式
注意Android里TextView控件的一个小坑,用android:theme来设置样式时动态载入的layout会丢失该样式 这个坑,必须要注意呀, 比如在用ListView的时候,如果在List_ ...
- Spring框架(6)---AspectJ实现AOP
AspectJ实现AOP 上一篇文章Spring框架(4)---AOP讲解铺垫,讲了一些基础AOP理解性的东西,那么这篇文章真正开始讲解AOP 通过AspectJ实现AOP要比普通的实现Aop要方便的 ...
- 使用java5的注解和Sping/AspectJ的AOP 来实现Memcached的缓存
使用java5的注解和Sping/AspectJ的AOP 来实现Memcached的缓存 今天要介绍的是Simple-Spring-Memcached,它封装了对MemCached的调用,使MemCa ...
- 8 -- 深入使用Spring -- 4...2 使用AspectJ实现AOP
8.4.2 使用AspectJ实现AOP AspectJ是一个基于Java语言的AOP框架.Spring 4.0 的AOP对AspectJ很好的集成. AspectJ是Java 语言的一个AOP实现, ...
- spring3: schema的aop与Aspectj的aop的区别
schema的aop如下: 接口: package chapter6.service; public interface IHelloAroundService { public void sayAr ...
- Spring整合AspectJ的AOP
学而时习之,不亦说乎! --<论语> 看这一篇之前最好先看前面关于AOP的两篇. http://www.cnblogs.com/z ...
- 利用基于@AspectJ的AOP实现权限控制
一. AOP与@AspectJ AOP 是 Aspect Oriented Programming 的缩写,意思是面向方面的编程.我们在系统开发中可以提取出很多共性的东西作为一个 Aspect,可以理 ...
随机推荐
- [转帖]20--Deployment常规操作
https://www.cnblogs.com/caodan01/p/15309966.html 目录 一.Deployment滚动更新 1.更新配置清单 2.设置镜像 kubectl set ima ...
- [转帖]TiFlash 简介
overview TiFlash 是 TiDB HTAP 形态的关键组件,它是 TiKV 的列存扩展,在提供了良好的隔离性的同时,也兼顾了强一致性.列存副本通过 Raft Learner 协议异步复制 ...
- [转帖]CENTOS6.5 没有/LIB64/LIBFUSE.SO.2的问题
yum install fuse-libs
- [转帖]关于iostat的问题,svctm数据不可信
使用FIO对磁盘进行压力测试,使用1个线程对磁盘进行随机读,设置单次read的数据块分别为128KB和1M,数据如下: (1)单次IO数据块为128KB (2)单次IO数据块为1M 从上面的数据可以看 ...
- [转帖]SPEC测试arm服务器性能,SPECJVM2008测试处理器性能_服务器评测与技术-中关村在线...
首先,我们使用SPECJVM2008测试最新至强E5处理器的虚拟化性能. SPECJVM2008是一种通用的多线程Java基准测试工具,它能够反映JRE(Java Runtime Environmen ...
- [1036]Linux启动时间分析
简述 今天有同事咨询:项目上有台服务器操作系统启动时间较长,如何分析? 果然,好问题都来自实践. 经过查找,对于所有基于systemd的系统,可以使用systemd-analyze来分析系统启动时间. ...
- Oracle 提示 用户在线,无法删除的清理方法
查找删除策略. select username,sid,serial# from v$session where username='FSSCDEC004'; alter system kill se ...
- CCPC Finals 2021 H Harie Programming Contest (网络流&支配树的妙用)
Link 题意: 给一个二分图,求有多少种方案删去恰好两个点,使得最大匹配数不变.\(n,m\le 2\times 10^5\). 二话不说先跑一遍 Dinic 网络流,设残量网络形成的图为 \(G\ ...
- vue中sync的使用原来这么简单
sync的使用场景 有些时候子组件需要修改父组件传递过来的prop, 要去改变父组件的状态的时候就需要使用aync 看见这里有些同学可能会问?? 不是说不可以修改父组件传递到子组件的值吗? 为啥要修改 ...
- TypeScript类的修饰符 public private protected的详细讲解
简单介绍一下public private protected public:当一个类的成员变量没有修饰的时候,默认的就是 public 进行修饰.外部是可以进行访问的. private属性只能够在父类 ...