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连接数据库返回数据类型,php从数据库读取数据,并以json格式返回数据的方法...

php中,从数据库读取数据,并以json格式返回数据。具体方法如下:第一步,定义相关变量$servername "localhost";$username "root";$password "root";$mysqlname "datatest";$json ;$da…

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…

php 去除标签内样式,PHP去除html标签,php标记及css样式代码参考

语法: string strip_tags(string str);传回值: 字串函式种类: 资料处理解析:本函式可去掉字串中包含的任何 HTML 及 PHP 的标记字串。若是字串的 HTML 及 PHP 标签原来就有错,例如少了大于的符号,则也会传回错误。而本函式和 fgetss() 有着相…

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

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

restful api php,RestfulAPI · ThinkPHP6.0接口开发与应用及uniapp快速入门(更新完毕) · 看云...

# Restful API>[success]Restful API是目前Web API 设计中比较流行的一种设计风格。## Restful API>[info]RESTful是一种软件架构风格、设计风格,而**不是**标准,只是提供了一组设计原则和约束条件。>[danger]对于这种风格,ThinkPHP…

php 向服务器发放请求,PHP客户端向服务器端发送请求并向远程服务器发送服务器端请求...

我的方案如下:>单击按钮时,客户端将向服务器端发送请求>一旦服务器端收到请求,它将向远程服务器发送另一个请求以获得结果>一旦响应到来,服务器端应该回应客户端的响应.客户$.post(login_server.php{act:"post",phone:phone,passwords:passwords…

php检查在线用户,php – 检查用户是否在线laravel

我有列last_activity,其中写入日期最后一个活动用户使用中间件.我如何检查在线用户以及何时注销?中间件:class LastActivityUser{/*** Handle an incoming request.** param \Illuminate\Http\Request $request* param \Closure $next* return mixed*/pu…

java 写文件缓存,java泛型实现文件缓存

package joyport.hbase;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.util.HashMap;/*** 文件缓存读写** author xiepengjoyport.com*/public class…

java方法重载的意义,java方法重载

class ChongZai{public void a(int a);public void a(Strting a);public void a(int a,int b);}如上就是一个重载了 而重载要满足一下条件:1.必须是同一个类2.方法名(也可以叫函数)一样3.参数类型不一样或参数数量不一样重载的作用:还是以上面的例子ChongZai cz new…

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

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

matlab光学教程,基于MATLAB的物理光学仿真

摘要:利用MATLAB编程语言对典型物理光学实验进行了仿真模拟,制作了包括干涉、衍射、信息光学、晶体光学实验在内的光学实验仿真平台,可应用到光学理论和实验教学中,使整个抽象的物理过程变得直观形象,增强了学生的学习…

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

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

php orm 链式,关于php:雄辩的ORM中的交叉和分页

大家好,我有3张桌子:具有以下属性的名为content的表:idnametable_type_idrelease_datepopularity另一个名为content_genres的表,具有以下属性:content_idgenres_id另一个具有以下属性的表,称为genres&#…

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

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

php取消转译代码,PHP在我不需要的时候进行转义

我有一个问题,即PHP在我不希望它出现在代码中的地方进行转义:$url_ stripslashes(((substr(strtolower($url),0,7)!"http://")? "http://".$url:$url));$host $this->googleDomains[mt_rand(0,count($this->googleDomains)-1)];$target "/s…

matlab给plc发送命令,想学习下如何将PLC发送的指令让软件接收到?

PLC作为下位机,接收上位机的执行命令,并将执行结果反馈给上位机。工具/原料电脑、PLC、USB转RS232数据线和RS232转RS485模块(或者USB转RS485)方法/步骤PLC与电脑线路连接,根据电脑的串口情况,1.电脑自带RS232串口,那么…

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

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

pupload 文件分块 php,基于Plupload实现Base64分割的文件上传方案

标题:基于Plupload实现Base64分割的文件上传方案关键词:文件上传、Base64、Plupload、Blob、分割上传领域:Web前端作者:孙振强日期:2018-04-13目录背景存在问题2.1. 体积增加1/32.2. 大文件上传不稳定方案思路3.1. 将服…

php imagick手册,PHP中使用Imagick实现各种图片效果实例

这篇文章主要介绍了PHP中使用Imagick实现各种图片效果实例,本文讲解了偏置图像、改变图片大imagick是一个功能强大的图像处理库。说是翻译 其实就是简要介绍imagick 的主要功能的或者说是我觉得比较实用的功能函数的介绍 以及使用的例子。因为本人的英语水平有限,所…