java aspectj_AspectJ基本用法

AOP虽然是方法论,但就好像OOP中的Java一样,一些先行者也开发了一套语言来支持AOP。目前用得比较火的就是AspectJ了,它是一种几乎和Java完全一样的语言,而且完全兼容Java(AspectJ应该就是一种扩展Java,但它不是像Groovy[[1]](file:///E:/Android-Internals/%E4%B8%93%E9%A2%98%E5%8D%B7/%E9%9A%8F%E7%AC%94%E7%B3%BB%E5%88%97/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Android%E4%B9%8BAOP.docx#_ftn1)那样的拓展。)。当然,除了使用AspectJ特殊的语言外,AspectJ还支持原生的Java,只要加上对应的AspectJ注解就好。所以,使用AspectJ有两种方法:

完全使用AspectJ的语言。这语言一点也不难,和Java几乎一样,也能在AspectJ中调用Java的任何类库。AspectJ只是多了一些关键词罢了。

或者使用纯Java语言开发,然后使用AspectJ注解,简称@AspectJ。

AspectJ的配置可以参考另一篇文章Android中使用AspectJ

Join Points介绍

Join Points是AspectJ中的一个关键概念。Join Points可以看作是程序运行时的一个执行点,比如:一个函数的调用可以看作是个Join Points,如Log.e()这个函数,e()可以看作是个Join Points,而调运e()的函数也可以认为是一个Join Points;设置一个变量,或者读取一个变量也可以是个Join Points;for循环也可以看作是Join Points。

理论上说,一个程序中很多地方都可以被看做是Join Points,但是AspectJ中,只有下面所示的几种执行点被认为是Join Points:

Join Points

说明

示例

method call

函数调用

比如调用Log.e(),这是一处JPoint

method execution

函数执行

比如Log.e()的执行内部,是一处Join Points。注意它和method call的区别。method call是调用某个函数的地方。而execution是某个函数执行的内部。

constructor call

构造函数调用

和method call类似

constructor execution

构造函数执行

和method execution类似

field get

获取某个变量

比如读取DemoActivity.debug成员

field set

设置某个变量

比如设置DemoActivity.debug成员

pre-initialization

Object在构造函数中做得一些工作。

initialization

Object在构造函数中做得工作

static initialization

类初始化

比如类的static{}

handler

异常处理

比如try catch(xxx)中,对应catch内的执行

advice execution

这个是AspectJ的内容,稍后再说

这里列出了AspectJ所认可的JoinPoints的类型。实际上,也就是你想把新的代码插在程序的哪个地方,是插在构造方法中,还是插在某个方法调用前,或者是插在某个方法中,这个地方就是Join Points,当然,不是所有地方都能给你插的,只有能插的地方,才叫Join Points。

Pointcuts介绍

一个程序会有多个Join Points,即使同一个函数,也还分为call和execution类型的Join Points,但并不是所有的Join Points都是我们关心的,Pointcuts就是提供一种使得开发者能够选择自己需要的JoinPoints的方法。

Advice

Advice就是我们插入的代码以何种方式插入,有Before还有After、Around。

看个例子

@Before("execution(* android.app.Activity.on**(..))")

public void onActivityMethodBefore(JoinPoint joinPoint) throws Throwable {

}

这里会分成几个部分,我们依次来看:

@Before:Advice,也就是具体的插入点

execution:处理Join Point的类型,例如call、execution

(* android.app.Activity.on**(..)):这个是最重要的表达式,第一个*表示返回值,*表示返回值为任意类型,后面这个就是典型的包名路径,其中可以包含 * 来进行通配,几个 * 没区别。同时,这里可以通过&&、||、!来进行条件组合。()代表这个方法的参数,你可以指定类型,例如android.os.Bundle,或者(..)这样来代表任意类型、任意个数的参数。

public void onActivityMethodBefore:实际切入的代码。

Before和After其实还是很好理解的,也就是在Pointcuts之前和之后,插入代码,那么Around呢,从字面含义上来讲,也就是在方法前后各插入代码,是的,他包含了Before和After的全部功能,代码如下:

@Around("execution(* com.xys.aspectjxdemo.MainActivity.testAOP())")

public void onActivityMethodAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

String key = proceedingJoinPoint.getSignature().toString();

Log.d(TAG, "onActivityMethodAroundFirst: " + key);

proceedingJoinPoint.proceed();

Log.d(TAG, "onActivityMethodAroundSecond: " + key);

}

其中,proceedingJoinPoint.proceed()代表执行原始的方法,在这之前、之后,都可以进行各种逻辑处理。

自定义Pointcuts

自定义Pointcuts可以让我们更加精确的切入一个或多个指定的切入点。

首先我们要定义一个注解类

@Retention(RetentionPolicy.CLASS)

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})

public @interface DebugTrace {

}

在需要插入代码的地方加入这个注解。如在MainActivity中加入,

public class MainActivity extends AppCompatActivity {

final String TAG = MainActivity.class.getSimpleName();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

logTest();

}

@DebugTrace

public void logTest() {

Log.e(TAG, "log test");

}

}

最后,创建切入代码

@Pointcut("execution(@com.kun.aspectjtest.aspect.DebugTrace * *..*.*(..))")

public void DebugTraceMethod() {}

@Before("DebugTraceMethod()")

public void beforeDebugTraceMethod(JoinPoint joinPoint) throws Throwable {

String key = joinPoint.getSignature().toString();

Log.e(TAG, "beforeDebugTraceMethod: " + key);

}

log如下

27b997677149

E22F03D2-C333-4A4C-9C7E-3DE97F221375.png

在AspectJ的切入点表达式中,我们前面都是使用的execution,实际上,还有一种类型——call,那么这两种语法有什么区别呢,对于Call来说:

Call(Before)

Pointcut{

Pointcut Method

}

Call(After)

对于Execution来说:

Pointcut{

execution(Before)

Pointcut Method

execution(After)

}

withincode

这个语法通常来进行一些切入点条件的过滤,作更加精确的切入控制。如下

public class MainActivity extends AppCompatActivity {

final String TAG = MainActivity.class.getSimpleName();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

aspectJ1();

aspectJ2();

aspectJ3();

}

public void aspectJTest() {

Log.e(TAG, "execute aspectJTest");

}

public void aspectJ1(){

aspectJTest();

}

public void aspectJ2(){

aspectJTest();

}

public void aspectJ3(){

aspectJTest();

}

}

aspectJ1(),aspectJ2(),aspectJ3()都调用了aspectJTest方法,但只想在aspectJ2调用aspectJTest时插入代码,这个时候就需要使用到Pointcut和withincode组合的方式,来精确定位切入点。

@Pointcut("(call(* *..aspectJTest()))&&withincode(* *..aspectJ2())")

public void invokeAspectJTestInAspectJ2() {

}

@Before("invokeAspectJTestInAspectJ2()")

public void beforeInvokeaspectJTestInAspectJ2(JoinPoint joinPoint) throws Throwable {

Log.e(TAG, "method:" + getMethodName(joinPoint).getName());

}

private MethodSignature getMethodName(JoinPoint joinPoint) {

if (joinPoint == null) return null;

return (MethodSignature) joinPoint.getSignature();

}

log如下

04-02 23:44:40.681 12107-12107/ E/MainActivity: execute aspectJTest

04-02 23:44:40.681 12107-12107/ E/AspectTest: method:aspectJTest

04-02 23:44:40.681 12107-12107/ E/MainActivity: execute aspectJTest

04-02 23:44:40.681 12107-12107/ E/MainActivity: execute aspectJTest

以上就是Aspecj的基本使用方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508107.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php json to object,PHP JSON_FORCE_OBJECT函数实现强转对象

JSON_FORCE_OBJECT在多级数组中,JSON_FORCE_OBJECT会将所有嵌套数值数组编码为对象。如果你只关注第一级数组(例如,使其适合作为MySQL JSON列),那么可以将第一级数组强制转换为对象,例如:$ json json_encode((object)…

php推送示例wordpress,给WordPress的编辑后台添加提示框的代码实例分享

WordPress 3.5 新添加了一个提示框功能,可以创建一个提示框,然后指向任何元素,比如下边的例子:本文就来教你怎么创建一个这样的提示框。首先需要添加提示框的脚本,这样才能使用提示框的 JS 方法。//挂载提示框脚本func…

jmeter php网站,jmeter实战之phpwind随机回帖/发帖

关键词:jmeter phpwind 性能测试一、性能需求1)性能需求:30min内,phpwind随机回帖/发帖,观察服务器性能的表现。2)需求分析:2.1 核心业务论坛系统的核心业务主要是登录、看帖、发帖、回帖,业务建模时应考虑…

php7改进,关注一下:PHP 7.3.7 正式发布 改进、修复的地方不少哦

PHP 7.3.7正式发布了。PHP(PHP:Hypertext Preprocessor)是一种在电脑上执行的脚本语言,主要是用途在于处理动态网页,也包含了命令列执行接口(command line interface),或者产生图形使用者接口(GUI)程式。版本主要还是修复 bug&…

php jwt token刷新方案,laravel JWT自动刷新 自定义验证器

在前面的文章中,我们引入了JWT的验证方式,但是在前面并没有做过多的处理,只是用JWT生成了一个token,那么今天来就解决后续问题为了保证用户信息的安全, 我们的生成的JWT不可能一直有效,我们在配置文件里边配…

2019java形势,2019Java开发还有哪些发展

相信已经有不少人在心里考虑着春节之后转行新工作了吧,而在众多行业中IT行业,特别是Java开发、Java程序员等岗位相信是很多人的首选。谁让现在程序员薪资这么高呢,但是现在互联网发展迅速,各类编程语言层出不穷,比如py…

mysql允许两个用户远程连接,配置MySQL服务允许用户远程连接

默认情况下,mysql只允许本地登录,如果要开启远程连接,则需要修改/etc/mysql/my.conf文件。一、修改/etc/mysql/my.conf找到bind-address 127.0.0.1这一行改为bind-address 0.0.0.0即可二、为需要远程登录的用户赋予权限1、新建用户远程连接…

php流程控制的类型有哪些,流程控制包括哪些内容

流程控制也称为控制流程,是计算机运算领域的用语,其内容包括在程序运行时,个别的指令或是陈述、子程序运行或求值的顺序,不论是在声明式编程语言或是函数编程语言中,都有类似的概念。控制流程(也称为流程控制)是计算机…

oracle11g创建闪回分区多大,Oracle闪回区大小预估

一个朋友问如何设置Oracle闪回区大小,有什么依据没有。查证官方文档,有如下描述For example, if you intend to setDB_FLASHBACK_RETENTION_TARGET to 24 hours, and if the database generates 20 GB of redo in a day, then a rule of thumb is to all…

查询linux服务器事物传输失败日志,查看fail2ban日志代替lastb查看登录失败记录

之前我曾经用shell脚本提取lastb登录失败超过指定次数的IP加入到iptables,来禁止这些IP登录主机,达到防止恶意攻击的目的。后来为了给主机提供更全面的防护,又安装了fail2ban。今天早上我收到fail2ban发过来的报警邮件提示我禁止了一个IP登录…

linux双屏播放视频,Ubuntu Linux下双屏显示解决方案

Ubuntu从起后居然把Windows的设置给记住了。显示ok。我晕。以前倒是也有过这问题,在双系统情况下,外接键盘的灯会继承Windows的早就有心弄个显示器,把笔记本的外接上,倒不是说非要2个屏幕来工作如何如何?只是因为我的本…

鸟哥linux群,【鸟哥的linux私房菜-学习笔记】linux的帐号与群组

linux的帐号与群组使用者标识符: UID 与 GIDID 与账号的对应就在 /etc/passwd 当中;计算机只认得ID(即数字),并不能区别账号;每个登陆的使用者至少都会取得两个 ID ,一个是使用者 ID (User ID ,简称 UID)、…

C语言中表示温度符号,摄氏度符号怎么打(SCI论文中摄氏度°C符号的正确输法)...

大家可能知道中文的摄氏度百思特网是一个字符,而且输入方法比较简单,可以用搜狗输入法,还可以输入 "sheshidu",第五个一般就是℃,甚至可以在网上或文献中复制粘贴。而英文的摄氏度C 却是两个字符&#xff0c…

android filehelper,为AndroidStudio开发mvp插件(MvpHelper)

如果觉得写mvp有点枯燥无味,我们可以做点 cool 的事情:做个 as 插件help.pngtodo-mvp: 基础的MVP架构。todo-mvp-loaders:基于MVP架构的实现,在获取数据的部分采用了loaders架构。todo-mvp-databinding: 基于MVP架构的实现,采用了…

android+5.q,MSM8909+Android5.1.1电池管理(2)--qpnp-linear-charger.txt驱动学习概要

MSM8909Android5.1.1电池管理(2)--qpnp-linear-charger.txt驱动学习概要参考文件\kernel\Documentation\power\qpnp-linear-charger.txt---下面是学习此文件\kernel\Documentation\devicetree\bindings\power\qpnp-linear-charger.txt1. 简介The QPNP linear charger drive…

岳阳鸿蒙数学培优阶梯训练,鸿蒙应用-呼吸训练app部分练习展示(开始)

本帖最后由 李洋水蛟龙 于 2020-12-20 18:11 编辑1.在主页面添加一个按钮并响应点击事件效果显示:图片1.png (404.17 KB, 下载次数: 0)2020-12-10 17:53 上传点击按钮“点我”下方便会显示“我被点击了”说明点击事件已完成代码如下:Index.hml文件中Hell…

android日期选择滚轮框架,GitHub - liwenzhi/wheelview: 滚轮效果的View,日期选择器

#wheelview滚动效果的View这段时间需要用到一个时间选择器,但是不能使用日期对话框,因为它是筛选条件框架下的,只能是View!这个WheelView改造后可以达到要求!这个wheelview框架使用的类不多,就几个&#xf…

大学计算机基础知识点图文,大学计算机基础知识点超详细总结

大学计算机基础知识点超详细总结 第一章 计算机及信息技术概述1. 电子计算机的发展历程①1946 年 2 月由宾夕法尼亚大学研制成功的 ENIAC 是世界上第一台电子数字计算机。 “诞生了一个电子的大脑” 致命缺陷:没有存储程序。②电子技术的发展促进了电子计算机的更新…

js复制html到粘贴板,用clipboard.js实现纯JS复制文本到剪切板

以前很多人都是用ZeroClipboard.js来实现网页复制内容,火端也是用它。ZeroClipboard是利用flash来实现的,ZeroClipboard兼容性很好,但是由于现在越来越多的浏览器不支持flash,导致一些没法正常使用了。今天火端开始使用clipboard.…

计算机设备的存放,计算机硬件储存设备与网络储存的发展现状

计算机的出现,改变了人们的生活和生产,而计算机硬件技术的发展,则为计算机储存开辟了新的发展方向和途径。而随着时代的进步,计算机储存技术的发展也是日新月异,现在我们所使用的云储存技术,就是储存技术发…