Android字节码插装--AspectJ

AspectJ:面向切面的框架,对Java通用的面向切面的扩展 AspectJ定义了Aop的语法,包含了一个专门的编译器(ajc:用于AspectJ和Java语言的字节码编译)用来生成遵守Java字节码规范的Class文件。 AspectJ编译过程

在AspectJ中有以下几个概念:

1.连接点(Joint Points)
2.切点(Pointcuts)
3.通知(Advice)
4.切面(AspectJ)
5.织入(Weaving)

1.连接点(Joint Points)

连接点是程序执行过程中明确的一点,连接点可以是方法或者构造函数的调用和执行,异常处理,字段赋值或访问等。
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/25caa37324c34c84a38b205e02a7e8e1~tplv-k3u1fbpfcp-zoom-1.image)

2.切点(Pointcuts)

Pointcuts:代码注入的位置,符合AspectJ规则的连接点很多,可以使用过滤规则过滤出我们关系的连接点,过滤规则就是切点。
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/87577e3211ff45f0a4ffebcb65254647~tplv-k3u1fbpfcp-zoom-1.image)
切点的匹配规则
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7bff7912f0c446d5b9641b2cc43ff957~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f6d7e7ecc3c34e338353d13f39a3d5b9~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/54af6ee9d44a4a79a886bbcb65d8a5bb~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cb6277b8b2cf441f8b0bc5a64f589fb5~tplv-k3u1fbpfcp-zoom-1.image)

3.通知(Advice)

Advice定义了横切行为,不同通知类型决定了插入的代码与切点所选择的每个连接点进行何种方式的交互。

4.切面(AspectJ)

AspectJ:Pointcut和Advice的组合看作切面。

5.织入(Weaving)

	Weaving:注入代码(Advice)到目标位置(join point)的过程。

代码示例

@Aspect
public class PointcutCategory {
   /**
    * 匹配任意返回值,任意方法,(任意参数)
    */
   @Around("execution(* *(..))")
   public Object weaveAllMethod(ProceedingJoinPoint joinPoint) throws Throwable{
   }
   
   /**
    * 匹配任意返回值,任意名称,(任意参数)的公共方法
    */
   @Pointcut("execution(public * *(..))")
   public void publicMethodPointcut() {

   }
  
   /**
    * 匹配 com.aspectj.practice 包及其子包中的所有方法
    */
   @Pointcut("within(com.aspectj.practice..*)")
   public void packagePointcut() {

   }
   
   /**
    * 匹配MainActivity类及其子类的所有方法
    */
   @Pointcut("within(com.aspectj.practice.MainActivity+)")
   public void subclassPointcut() {

   }
   
   /**
    * 匹配类 MainActivity 的所有方法
    */
   @Pointcut("within(com.aspectj.practice.SubMainActivity)")
   public void classPointcut() {

   }
   
   /**
    * 匹配所有实现 User 的类的所有方法
    */
   @Pointcut("within(com.aspectj.practice.framework.interfaces.User+)")
   public void interfaceIpm() {

   }
   
   /**
    * 匹配 test 开头,任意返回值的方法
    */
   @Pointcut("execution(* test*())")
   public void withSetPrefixPointcut() {

   }

   /**
    * 匹配 userImp 的所有方法
    */
   @Pointcut("execution(* com.aspectj.practice.userImp.*(..))")
   public void allMethodPointcut() {

   }

   /**
    * 匹配 userImp 的所有私有方法
    */
   @Pointcut("execution(private * com.aspectj.practice.userImp.*(..))")
   public void allPrivateMethodPointcut() {

   }
   
   /**
    * 匹配 userImp 的所有公有方法
    */
   @Pointcut("execution(public * com.aspectj.practice.userImp.*(int, ..))")
   public void allPublicMethodWithIntPointcut() {

   }
   
   /**
    * @within 匹配标注了注解 ClassAnnotation 的类及其子孙的所有方法
    */
   @Pointcut("@within(com.aspectj.annotation.ClassAnnotation)")
   public void withAnnotationClassPointcut() {

   }
   
   /**
    * 匹配使用了注解 MethodAnnotation 的方法
    */
   @Pointcut("@annotation(com.aspectj.annotation.MethodAnnotation)")
   public void withAnnotationMethodPointcut() {

   }

   /**
    * 匹配使用了注解 MethodAnnotation 的方法
    */
   @Pointcut("execution(@com.aspectj.annotation.MethodAnnotation * *(..))")
   public void withAnnotationMethodPointcut2() {

   }
   
   /**
    * 匹配任意实现了接口User的目标对象的方法并且方法使用了注解 MethodAnnotation
    */
   @Pointcut("target(com.aspectj.practice.framework.interfaces.User) && @annotation(com.aspectj.annotation.MethodAnnotation)")
   public void withOperatorPointcut() {

   }
   
   /**
    * 匹配任意实现了接口User的目标对象的方法并且方法名称为 add
    */
   @Pointcut("target(com.aspectj.practice.framework.interfaces.User) && execution(* com.aspectj.practice.framework.interfaces.User.add(..))")
   public void withOperatorAddNamePointcut() {

   }
   
   @Pointcut("call(* com.aspectj.practice.framework.interfaces.User.*(..))")
   public void methodCallPointcut() {
   
   }
   
   /**
    * 匹配 MemberDto 的属性 userName 的赋值
    */
   @Pointcut("set(java.lang.String com.aspectj.practice.dto.MemberDto.userName)")
   public void fieldSetPointCut() {

   }
   
   /**
    * 匹配 MemberDto 的属性 userName的获取
    */
   @Pointcut("get(java.lang.String com.aspectj.practice.dto.MemberDto.userName)")
   public void fieldGetPointCut() {

   }
   
   /**
    * 匹配 MemberDto 构造函数
    */
   @Pointcut("call(com.aspectj.practice.dto.MemberDto.new(..))")
   public void constructorCallPointcut() {

   }
   
   .......
}