ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AOP与OOP有什么区别,谈谈AOP的原理是什么(1),android系统四层架构

2021-12-13 13:32:01  阅读:200  来源: 互联网

标签:Java 编译 OOP Android AOP android AspectJ


// do something
long end = System.currentTimeMillis() - start;
}
}

二、AOP代码注入时机

代码注入主要注解机制,根据注解时机的不同,主要分为运行时、加载时和编译时。

运行时:你的代码对增强代码的需求很明确,比如,必须使用动态代理(这可以说并不是真正的代码注入)。 加载时:当目标类被Dalvik或者ART加载的时候修改才会被执行。这是对Java字节码文件或者Android的dex文件进行的注入操作。 编译时:在打包发布程序之前,通过向编译过程添加额外的步骤来修改被编译的类。aspect切面编程正是运用到编译时

###三、AOP的几种实现方式

  • Java 中的动态代理,运行时动态创建 Proxy 类实例
  • APT,注解处理器,编译时生成 .java 代码
  • Javassist for Android:一个移植到Android平台的非常知名的操纵字节码的java库,对 class 字节码进行修改
  • AspectJ:和Java语言无缝衔接的面向切面的编程的扩展工具(可用于Android)。

###四,Android中使用 AspectJ

代表项目:Hugo(打印每个方法的执行时间) sa-sdk-android(全埋点技术)

#####(1)原理

AspectJ 意思就是Java的Aspect,Java的AOP。它的核心是ajc(编译器 aspectjtools)和 weaver(织入器 aspectjweaver)。

ajc编译器:基于Java编译器之上的,它是用来编译.aj文件,aspectj在Java编译器的基础上增加了一些它自己的关键字和方法。因此,ajc也可以编译Java代码。

weaver织入器:为了在java编译器上使用AspectJ而不依赖于Ajc编译器,aspectJ 5出现了 @AspectJ,使用注释的方式编写AspectJ代码,可以在任何Java编译器上使用。 由于AndroidStudio默认是没有ajc编译器的,所以在Android中使用@AspectJ来编写。它在代码的编译期间扫描目标程序,根据切点(PointCut)匹配,将开发者编写的Aspect程序编织(Weave)到目标程序的.class文件中,对目标程序作了重构(重构单位是JoinPoint),目的就是建立目标程序与Aspect程序的连接(获得执行的对象、方法、参数等上下文信息),从而达到AOP的目的。

#####(2)AspectJ 术语

切面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。其实就是共有功能的实现。如日志切面、权限切面、事务切面等。

通知(Advice):是切面的具体实现。以目标方法为参照点,根据放置的地方不同,可分为

  1. 前置通知(Before)、
  2. 后置通知(AfterReturning)、
  3. 异常通知(AfterThrowing)、
  4. 最终通知(After)
  5. 环绕通知(Around)5种。

在实际应用中通常是切面类中的一个方法,具体属于哪类通知由配置指定的。

切入点(Pointcut):用于定义通知应该切入到哪些连接点上。不同的通知通常需要切入到不同的连接点上,这种精准的匹配是由切入点的正则表达式来定义的。 连接点(JoinPoint):就是程序在运行过程中能够插入切面的地点。例如,方法调用、异常抛出或字段修改等。

目标对象(Target Object):包含连接点的对象,也被称作被通知或被代理对象。这些对象中已经只剩下干干净净的核心业务逻辑代码了,所有的共有功能等代码则是等待AOP容器的切入。

**AOP代理(AOP Pr

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

oxy)**:将通知应用到目标对象之后被动态创建的对象。可以简单地理解为,代理对象的功能等于目标对象的核心业务逻辑功能加上共有功能。代理对象对于使用者而言是透明的,是程序运行过程中的产物。

编织(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程。这个过程可以发生在编译期、类装载期及运行期,当然不同的发生点有着不同的前提条件。譬如发生在编译期的话,就要求有一个支持这种AOP实现的特殊编译器(如AspectJ编译器);

发生在类装载期,就要求有一个支持AOP实现的特殊类装载器;只有发生在运行期,则可直接通过Java语言的反射机制与动态代理机制来动态实现(如摇一摇)。

**引入(Introduction):**添加方法或字段到被通知的类。

######(3)在Android项目中使用AspectJ

上海沪江团队的 gradle_plugin_android_aspectjx 一个基于AspectJ并在此基础上扩展出来可应用于Android开发平台的AOP框架,可作用于java源码,class文件及jar包,同时支持kotlin的应用。

AOP的用处非常广,从spring到Android,各个地方都有使用,特别是在后端,Spring中已经使用的非常方便了,而且功能非常强大,但是在Android中,AspectJ的实现是略阉割的版本,并不是所有功能都支持,但对于一般的客户端开发来说,已经完全足够用了。

#####(4)以 AspectJX 接入说明

  • 首先,需要在项目根目录的build.gradle中增加依赖:

buildscript {
repositories {
jcenter()
}
dependencies {
classpath ‘com.android.tools.build:gradle:2.3.3’
classpath ‘com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4’
}
}

  • 然后module项目的 build.gradle 中加入 AspectJ 的依赖:

apply plugin: ‘android-aspectjx’
dependencies {
compile ‘org.aspectj:aspectjrt:1.8.+’
}

aspectjx {
//排除所有package路径中包含android.support的class文件及库(jar文件)
exclude ‘org.apache.httpcomponents’
exclude ‘android.support’
}

  • 我们通过一段简单的代码来了解下基本的使用方法和功能,新建一个AspectTest类文件,代码如下:

@Aspect
public class AspectTest {

private static final String TAG = “xuyisheng”;

@Before(“execution(* android.app.Activity.on**(…))”)
public void onActivityMethodBefore(JoinPoint joinPoint) throws Throwable {
String key = joinPoint.getSignature().toString();
Log.e(TAG, "onActivityMethodBefore: " + key);
}

@After(“execution(* android.app.Activity.on**(…))”)
public void onActivityMethodAfter(JoinPoint joinPoint) throws Throwable {
String key = joinPoint.getSignature().toString();
Log.e(TAG, "onActivityMethodAfter: " + key);
}

@Around(“execution(* android.app.Activity.on**(…))”)
public void onActivityMethodAfter(ProceedingJoinPoint joinPoint) throws Throwable {
String key = joinPoint.getSignature().toString();
Log.e(TAG, "onActivityMethodBefore: " + key);
joinPoint.proceed();
Log.e(TAG, "onActivityMethodAfter: " + key);
}
}

在类的最开始,我们使用 @Aspect 注解来定义这样一个AspectJ文件,编译器在编译的时候,就会自动去解析,并不需要主动去调用AspectJ类里面的代码。

(5)编织速度优化建议
  • 尽量使用精确的匹配规则,降低匹配时间。
  • 排除不需要扫描的包。
    通过这种方式编译后,我们来看下生成的代码是怎样的。AspectJ的原理实际上是在编译的时候,根据一定的规则解析,然后插入一些代码,通过aspectj生成的代码,会在Build目录下:

四、总结:

#####Aspectj:

  • AspectJ除了hook之外,AspectJ还可以为目标类添加变量,接口。另外,AspectJ也有抽象,继承等各种更高级的玩法。它能够在编译期间直接修改源代码生成class。
  • AspectJ语法比较多,但是掌握几个简单常用的,就能实现绝大多数切片,完全兼容Java(纯Java语言开发,然后使用AspectJ注解,简称@AspectJ。)

关于我

更多信息可以点击关于我 , 非常希望和大家一起交流 , 共同进步
也可以扫一扫, 目前是一名程序员,不仅分享 Android开发相关知识,同时还分享技术人成长历程,包括个人总结,职场经验,面试经验等,希望能让你少走一点弯路。

望和大家一起交流 , 共同进步
也可以扫一扫, 目前是一名程序员,不仅分享 Android开发相关知识,同时还分享技术人成长历程,包括个人总结,职场经验,面试经验等,希望能让你少走一点弯路。

[外链图片转存中…(img-Ow6fUNJp-1639373138043)]

标签:Java,编译,OOP,Android,AOP,android,AspectJ
来源: https://blog.csdn.net/m0_64604893/article/details/121903338

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有