AOP面向切面编程简单使用

一、AOP介绍

1、AOP是什么?

AOP即为面向切面编程,和Java的OOP面向对象编程一样,都是一种编程思想,一些先行者已经为面向切面编程开发了一套语言来支持。

2、AOP的作用是什么?

通过预编译的形式和运行期动态代理,来改变原来的执行结果。

3、AOP的特点?

(1)使原执行逻辑和切面逻辑进行解耦
(2)对源代码侵入性低
(3)容易扩展辅助功能(比如Android的埋点,跳转前的网络检查,权限检查等等,都不属于面向对象的模块内的东西,但是又是各个模块通用的东西)

4、AspectJ的介绍

AspectJ是一种几乎和Java一样的编程语言,完全兼容Java。在Android中通过AspectJ实现AOP有两种形式,第一种是使用AspectJ这种语言。
第二种仍然使用Java语言,给Java语言打上一些标签,能让AspectJ的编译器识别即可。
在Android中使用AspectJ,说白点,就是在编译成点class的过程中,不再使用Java的编译器了,而是使用AspectJ的编译器。
这个编译器和Java的编译器没太多的区别,唯一是,它会根据@Aspect标签的类,找到切点和切面,再反推去找到被切点标记的注解,看哪些方法用到这些注解。
然后进行一个代码植入方案。本质上没有性能的问题。

二、在Android中的使用

1、定义一个注解

/**
 * Target表示这个注解用在什么地方,当前是Method方法上。有类、构造函数、函数、属性等选项
 * Retention表示注解保留多久
 * 1、RUNTIME表示运行时,即编译后,注解仍然在,并且会随着class加载进入JVM
 * 2、CLASS表示编译时,即编译后,注解仍然在,但是JVM加载class文件时会被抛弃掉
 * 3、SOURCE表示源码,即编译后,注解就被编译器忽略了不存在了
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AddPoint {
    String value();
}

2、定义一个切面和切点

/**
 * @Aspect定义该类为切点切面处理类
 */
@Aspect
public class MyAspect {
    /**
     * @Pointcut表示切点 execution表示用在方法的执行内部
     * call表示用在方法的调用处
     * get/set一般用在变量、属性的使用上
     * @com.zbh.aopdemo.AddPoint表示注解类所在的全地址,通过这个声明,就知道这个切点用在被这个地址注解的属性或者方法上了 
     * * * (..)表示被这个注解的所有方法,不管什么参数的,都要进行切点和切面处理
     */
    @Pointcut("execution(@com.zbh.aopdemo.AddPoint * * (..))")
    public void addPoint() {

    }

    /**
     * @Before表示前置通知,切点前执行,方法执行前这里先执行
     */
    @Before("addPoint()")
    public void testBefore() {
        Log.i("zhangbh", "Test Run Before");
    }

    /**
     * @Around表示环绕通知,切点前后执行,相当于下面的代码会代替被注解标记的代码,其中point.proceed()就是把原来方法的代码挪到这一块
     * return null的地方,那么切点的方法就不会被调用。比如下面这个执行,如果注解标记的@AddPoint("ABC"),那么该方法的方法体最终是不会被调用的
     * @AddPoint("Test")这样,方法体就会被调用,可以理解为替换到这里面来
     */
    @Around("addPoint()")
    public Object dealPoint(ProceedingJoinPoint point) throws Throwable {
        MethodSignature ms = (MethodSignature) point.getSignature();
        AddPoint addPoint = ms.getMethod().getAnnotation(AddPoint.class);
        String value = addPoint.value();
        if ("Test".equals(value)) {
            Log.i("zhangbh", "Test Run Start");
            Object object = point.proceed();
            Log.i("zhangbh", "Test Run End");
            return object;
        }
        return null;
    }

    /**
     * @After表示后置通知,切点后执行,方法执行后这里才执行
     */
    @After("addPoint()")
    public void testAfter() {
        Log.i("zhangbh", "Test Run After");
    }
}

你可能感兴趣的:(设计模式,AOP,面向切面)