一种Android端基于AOP和AspectJ的日志自动埋点方法及系统与流程

文档序号:11690918阅读:546来源:国知局
一种Android端基于AOP和AspectJ的日志自动埋点方法及系统与流程

本发明涉及android端软件编程技术领域,尤其涉及一种android端基于aop和aspectj的日志自动埋点方法及系统。



背景技术:

在目前android客户端项目开发过程中,基本是多人合作开发模式,在开发过程中需要调试打印log日志以便记录和观察功能模块执行是否有误,log日志对于开发人员来说是极为重要的检测程序流程逻辑是否正确的检测手段,在多人合作开发过程中由于每个人开发习惯和行为可能不一致,这样会导致代码杂乱。

aspectj的动机是发现那些使用传统的编程方法无法很好处理的问题。考虑一个要在某些应用中实施安全策略的问题。安全性是贯穿于系统所有模块间的问题,每个模块都需要应用安全机制才能保证整个系统的安全性,这里的安全策略的实施问题就是一个横切关注点,使用传统的编程解决此问题非常的困难而且容易产生差错。

传统的面向对象编程中,每个单元就是一个类,而类似于安全性这方面的问题,它们通常不能集中在一个类中处理因为它们横跨多个类,这就导致了代码无法重用,可维护性差而且产生了大量代码冗余。



技术实现要素:

本发明要解决的技术问题在于针对现有技术中由于不同开发人员的不同开发习惯,导致日志代码杂乱,传统的面向对象编程可维护性差而且产生了大量代码冗余的缺陷,提供一种android端基于aop和aspectj的日志自动埋点方法及系统。

本发明解决其技术问题所采用的技术方案是:

本发明提供一种android端基于aop和aspectj的日志自动埋点方法,包括以下步骤:

编写用于日志埋点的自定义注解;

引用面向切面框架的aspectj编译方式;

编写aspectj切面程序代码,对需要进行日志埋点的位置定义切入点匹配规则,切入点匹配规则包括多个用通配符或正则表达式表示的连接点,连接点为自定义注解注入的目标入口,在连接点上的相应位置执行自定义注解中的对日志进行自动埋点的动作;

程序运行时向日志中自动插入埋点,并通过程序自动输出或使用自定义注解标注的方式查看日志输出。

进一步地,本发明的自定义注解的目标元素类型包括构造函数、方法和字段,注解的作用时段为运行时有效。

进一步地,本发明的引用aspectj编译的方法包括:

通过在gradle构建脚本中,定义任务来执行aspectj编译;

使用第三方aspectj集成插件执行aspectj编译。

进一步地,本发明的定义的切入点匹配规则包括:

activity和fragment类的切入点,用于自动打印activity和fragment生命周期函数执行时间和时长;

函数方法切入点,用于自动打印目标函数的执行时长、传入参数和返回结果;

属性切入点,用于自动打印类中定义的属性值变化状况。

进一步地,本发明的实现activity和fragment生命周期函数执行时间和时长自动打印的方法为:

通过切入点函数表示所有继承自activity和fragment的类中前缀带有on的函数方法切入点,在对应的切入点函数中执行记录时间差和统计时长的目标方法,将执行结果按格式打印到日志中。

进一步地,本发明的实现目标函数的执行时长、传入参数和返回结果的自动打印的方法为:

通过切入点函数匹配自定义注解中的函数方法切入点,对所有匹配到的函数方法进行代码注入,通过api获取到该函数方法的参数值,参数值包括目标函数的执行时长、传入参数和返回结果,将执行结果按格式打印到日志中。

进一步地,本发明的实现类中定义的属性值变化状况的自动打印的方法为:

通过切入点函数匹配自定义注解中的属性切入点,对所有匹配到的属性进行代码注入,通过api获取到该属性值的变化状况,将执行结果按格式打印到日志中。

本发明提供一种android端基于aop和aspectj的日志自动埋点系统,包括:

自动注解单元,用于编写用于日志埋点的自定义注解;

aspectj编译单元,用于引用面向切面框架的aspectj编译方式;

切面程序单元,用于编写aspectj切面程序代码,对需要进行日志埋点的位置定义切入点匹配规则,切入点匹配规则包括多个用通配符或正则表达式表示的连接点,连接点为自定义注解注入的目标入口,在连接点上的相应位置执行自定义注解中的对日志进行自动埋点的动作;

日志输出单元,用于在程序运行时向日志中自动插入埋点,并通过程序自动输出或使用自定义注解标注的方式查看日志输出。

本发明产生的有益效果是:本发明的android端基于aop和aspectj的日志自动埋点方法,利用aop切面编程思想,通过aspecj技术基于自定义注解方式实现log日志自动埋点,统一log日志风格,使用注解方式提高开发量,将可以有效减少开发代码量和实现代码解耦提高开发效率;本发明能够统一多人开发过程中日志输出格式,提高开发效率和代码解耦;利用aop切面编程思想实现运行时代码自动插入log自动埋点,便于阅读和分析log日志。

附图说明

下面将结合附图及实施例对本发明作进一步说明,附图中:

图1是本发明实施例的流程图;

图2是本发明实施例的系统框图;

图3是本发明实施例的切面示意图。

具体实施方式

为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅用以解释本发明,并不用于限定本发明。

术语说明:

aop:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。aop是oop的延续,是软件开发中的一个热点,利用aop可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

aspectj:一种基于java平台的面向切面编程的语言,定义了各种连接点集合来实现aop的概念,有如下概念词汇。

advice(通知):典型的advice类型有before、after和around,分别表示在目标方法执行之前、执行后和完全替代目标方法执行的代码。

jointpoint(连接点):程序中可能作为代码注入目标的特定的点和入口。

pointcut(切入点):告诉代码注入工具,在何处注入一段特定代码的表达式。

aspect(切面):pointcut和advice的组合看做切面。

weaving(织入):注入代码(advices)到目标位置(jointpoints)的过程。

自定义注解:使用@interface自定义注解时,自动继承了java.lang.annotation.annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、class、string、enum)。可以通过default来声明参数的默认值。

如图1所示,本发明实施例的android端基于aop和aspectj的日志自动埋点方法,包括以下步骤:

s1、编写用于日志埋点的自定义注解;自定义注解的目标元素类型包括构造函数、方法和字段,注解的作用时段为运行时有效。

s2、引用面向切面框架的aspectj编译方式;引用aspectj编译的方法包括:

通过在gradle构建脚本中,定义任务来执行aspectj编译;

使用第三方aspectj集成插件gradle-android-aspectj-plugin使执行aspectj编译。

s3、编写aspectj切面程序代码,对需要进行日志埋点的位置定义切入点匹配规则,切入点匹配规则包括多个用通配符或正则表达式表示的连接点,连接点为自定义注解注入的目标入口,在连接点上的相应位置执行自定义注解中的对日志进行自动埋点的动作;

s4、程序运行时向日志中自动插入埋点,并通过程序自动输出或使用自定义注解标注的方式查看日志输出。

定义的切入点匹配规则包括:

针对所有继承自android.app.activity的类的以on开头的方法执行点切入,用于自动打印activity生命周期函数执行时间和时长;

针对所有继承android.support.v4.app.fragment的类的以on开头的方法执行点切入,用于自动打印fragment生命周期函数执行时间和时长;

函数方法切入点,用于自动打印目标函数的执行时长、传入参数和返回结果;

针对类中的属性切入点,用于自动打印类中定义的属性值变化状况。

实现activity和fragment生命周期函数执行时间和时长自动打印的方法为:

通过切入点函数表示所有继承自activity和fragment的类中前缀带有on的函数方法切入点,在对应的切入点函数中执行记录时间差和统计时长的目标方法,将执行结果按格式打印到日志中。

本实施例中activity的切入点函数为:

pointcut("execution(*android.app.activity.on*(..))&&this(activity)")

fragment的切入点函数为:

pointcut("execution(*android.support.v4.app.fragment+.on*(..))&&this(fragment)")

在切入点函数里执行joinpoint.proceed()前后记录时间差,统计时长,输出日志按格式打印内容。

实现目标函数的执行时长、传入参数和返回结果的自动打印的方法为:

通过切入点函数匹配自定义注解中的函数方法切入点,对所有匹配到的函数方法进行代码注入,通过api获取到该函数方法的参数值,参数值包括目标函数的执行时长、传入参数和返回结果,将执行结果按格式打印到日志中。

在本实施例中,采用的具体方法和函数为:

在around("(execution(@com.app.aop.annotation.logfunc**.*(..))&&target(object)&&this(object))")切入方法中,通过proceedingjoinpoint类的getsignature()方法获取到methodsignature对象,通过getparameternames()方法获取函数传入参名称,通过proceedingjoinpoint.getargs()方法获取函数参数值,输出日志按格式打印内容。

实现类中定义的属性值变化状况的自动打印的方法为:

通过切入点函数匹配自定义注解中的属性切入点,对所有匹配到的属性进行代码注入,通过api获取到该属性值的变化状况,将执行结果按格式打印到日志中。

在本实施例中,采用的具体方法和函数为:

在around("set(@com.app.aop.annotation.loganyway**)&&args(newval)&&target(t)")切入方法中,通过proceedingjoinpoint.getsignature()方法获取fieldsignature对象,再通过fieldsignature.getname()方法获取属性名称,通过fieldsignature.getfield()方法获取到field对象,再获取属性新赋予的值,输出日志按格式打印内容。

如图2所示,本发明实施例的android端基于aop和aspectj的日志自动埋点系统,包括:

自动注解单元,用于编写用于日志埋点的自定义注解;

aspectj编译单元,用于引用面向切面框架的aspectj编译方式;

切面程序单元,用于编写aspectj切面程序代码,对需要进行日志埋点的位置定义切入点匹配规则,切入点匹配规则包括多个用通配符或正则表达式表示的连接点,连接点为自定义注解注入的目标入口,在连接点上的相应位置执行自定义注解中的对日志进行自动埋点的动作;

日志输出单元,用于在程序运行时向日志中自动插入埋点,并通过程序自动输出或使用自定义注解标注的方式查看日志输出。

如图3所示,在本发明的另一个具体实施例中:

实现原理的是在android客户端使用aop思想通过aspectj基于自定义注解方式实现项目开发过程中日志记录埋点。

aop并没有帮助我们解决任何新的问题,它只是提供了一种更好的办法,能够用更少的工作量来解决现有的一些问题,并且使得系统更加健壮,可维护性更好。同时,它让我们在进行系统架构和模块设计的时候多了新的选择和新的思路,aspectj帮我们实现了这些。

主要实现流程如下:

1、自定义注解logfunc

注解可以作用的目标:

@target({elementtype.constructor,elementtype.method,

elementtype.field});

注解的作用时段:@retention(retentionpolicy.runtime)

代码如下:

@target({elementtype.constructor,elementtype.method,elementtype.field})

@retention(retentionpolicy.runtime)

@documented

public@interfacelogfunc{

}

2、引用aspectj编译,通过在gradle构建脚本中,定义任务来使得项目执行ajc编译,将aop的module编织进入目标工程中,达到非侵入式aop的目的;另外可使用第三方aspectj集成插件gradle-android-aspectj-plugin

3、编写aspectj切面程序代码,创建@aspect类traceaspect

定义pointcut切点匹配规则;

a.@pointcut("execution(*android.app.activity.on*(..))&&this(activity)")//针对所有继承自android.app.activity的类的以on开头的方法执行点切入;

b.@pointcut("execution(*android.support.v4.app.fragment+.on*(..))&&this(fragment)")//所有继承android.support.v4.app.fragment的类的以on开头的方法;

c.@pointcut("(execution(@com.app.aop.annotation.logfunc**.*(..))&&target(object)&&this(object))||execution(@com.app.aop.annotation.logfuncpublicstatic**(..))")//函数方法切入点;

d.@pointcut("set(@com.app.aop.annotation.loganyway**)&&args(newval)&&target(t)")//针对类中的属性切入点;

实现以上切入点规则的advice(通知):在joinpoint上执行的一个动作,通知一般通过拦截器调用,向连接点注入的代码。

a.对于activity和fragment生命周期函数执行的log监控aspectj实现如下:

在@pointcut("execution(*android.app.activity.on*(..))&&this(activity)")切入代码点函数里执行joinpoint.proceed()前后记录时间差,统计时长

b.对于函数的执行时长、传入参数和返回结果aspectj实现如下

在@around("(execution(@com.app.aop.annotation.logfunc**.*(..))&&target(object)&&this(object))")切入方法中通过proceedingjoinpoint的getsignature()获取到methodsignature,在通过getparameternames()获取函数入参名称,proceedingjoinpoint.getargs()获取函数参数值,然后输出log按格式打印内容。

在@afterreturning(value="(execution(@com.app.aop.annotation.logfunc**.*(..))&&target(object)&&this(object))",argnames="rtv",returning="rtv")切入方法中打印函数返回结果rtv。

c.对于类中定义的属性值变化状况aspectj实现如下

在@around("set(@com.app.aop.annotation.loganyway**)&&

args(newval)&&target(t)")切入方法中,通过

proceedingjoinpoint.getsignature)获取fieldsignature;

再通过fieldsignature.getname()获取属性名称;

通过fieldsignature.getfield()获取到field在获取属性新赋予的值并打印

4、在项目中使用自定义注解logfunc标注需要自动埋点打印log的位置即可。

例如对变量log埋点只需@logfunc标注即可在程序运行时看到log输出。

对于activity和fragment生命周期函数可在程序运行时自动看到log输出,不需其他标注。

本发明的有益效果为:

1、统一多人开发过程中日志输出格式,提高开发效率和代码解耦;

2、利用aop切面编程思想实现运行时代码自动插入log自动埋点,便于阅读和分析log日志。

应当理解的是,对本领域普通技术人员来说,可以根据上述说明加以改进或变换,而所有这些改进和变换都应属于本发明所附权利要求的保护范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1