Android(安卓)Studio中AspectJ的简单使用一(自定义PointCut)
使用自定义注解的方式,步骤如下
1.创建自定义注解;
2.创建操作类(切入文件);
3.调用注解。
一、创建自定义注解。
代码如下。
package cm.richeninfo.com.astestaspect20180309.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * Created by wangxiaowu on 2018/3/9 14:08 * decribe * 注解类 */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface BehaviorTrace { String value();}
注意:
@Target、@Retention、@interface
备注:
java中元注解有四个: @Retention @Target @Document @Inherited;
@Retention:注解的保留位置
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target:注解的作用目标
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
二、创建操作类
代码如下。
package cm.richeninfo.com.astestaspect20180309.aspect;import android.util.Log;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.annotation.RequiredTypes;import org.aspectj.lang.reflect.MethodSignature;import java.util.Objects;import cm.richeninfo.com.astestaspect20180309.annotation.BehaviorTrace;/** * Created by wangxiaowu on 2018/3/9 14:36 * decribe */@Aspectpublic class BehaviorTraceAspect { //关联的注解类cm.richeninfo.com.astestaspect20180309.annotation.BehaviorTrace @Pointcut("execution(@cm.richeninfo.com.astestaspect20180309.annotation.BehaviorTrace * *(..))") public void methodAnnotatedWithBehaviorTraceAspect(){ //下面的代码没有执行 Log.d("system.out","methodAnnotated**********************"); }// @Before("methodAnnotatedWithBehaviorTraceAspect()")// public void beforeMethod() throws Throwable{// Log.v("system.out","before method is executed");// }//// @After("methodAnnotatedWithBehaviorTraceAspect()")// public void afterMethod() throws Throwable{// Log.v("system.out","after method is executed");// } //关联的操作methodAnnotatedWithBehaviorTraceAspect() @Around("methodAnnotatedWithBehaviorTraceAspect()") public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable{ Object result=null; if(null!=joinPoint){ MethodSignature methodSignature=(MethodSignature)joinPoint.getSignature(); String className=methodSignature.getDeclaringType().getSimpleName(); String methodName=methodSignature.getName(); String funName=methodSignature.getMethod().getAnnotation(BehaviorTrace.class).value(); Log.d("system.out","arround method is executed.before"); //统计时间 long begin=System.currentTimeMillis(); result=joinPoint.proceed(); long duration=System.currentTimeMillis()-begin; Log.d("system.out",String.format("around method is executed .after 功能:%s,%s类的%s方法执行了,用时%d ms",funName,className,methodName,duration)); return result; } return result; }}
注意:
类必须要加上@Aspect注解。再声明一个方法作为切点,这个方法需要加上注解:
@pointcut(execution(@全类名 * *(. .))) 后面的两个表示*匹配所有的方法名,两个.表示匹配所有的方法参数
备注:
AspectJ的切入点表达式中,可以用execution、call。
对于Call来说:
Call(Before) Pointcut{ Pointcut Method } Call(After) 对于Execution来说: Pointcut{ execution(Before) Pointcut Method execution(After) }三、调用注解
代码如下。
package cm.richeninfo.com.astestaspect20180309;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import cm.richeninfo.com.astestaspect20180309.annotation.BehaviorTrace;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.activity_main_tv1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { testAspect(); } }); } @BehaviorTrace("测试 aspect") private int testAspect(){ Log.v("system.out","testAspect inner is executed"); return 100; }}
更多相关文章
- Android(安卓)EditText 不弹出输入法总结
- android 判断EditText中输入的值是数字、字母还是汉字的方法
- android 怎样为多媒体文件生成缩略图
- Android实现拍照、录像、录音代码范例
- Android实现截屏的方法
- android捕获全局异常处理,不闪退
- android 完美的ListView实现【原创】
- Android(安卓)popupWindow响应back按键并关闭
- Android(安卓)判断网络是否可用 & 获取IP地址 & 获取以太网口MAC