spring-aop

术语说明

  • 目标target,被增强的对象
  • 连接点Joinpoint,指的是可以被拦截到的方法
  • 切入点Pointcut,指的是真正被拦截到的方法
  • 通知Advice,指的是拦截到切入点后要做的事情
  • 织入Weaving,指的是将通知Advice应用到目标target的这个过程
  • 代理Proxy,目标Target被增强后,产生了一个代理对象
  • 切面Aspect,切入点Pointcut和通知Advice的组合

实现原理

  • JDK动态代理(目标类实现了接口)
  • Cglib动态代理(目标类无接口实现)

切入点表达式

参数包括:execution("修饰符 返回值类型 包.类.方法名(参数..) throws异常")

  • 修饰符(举例):一般省略
* 任意
public 公共访问
  • 返回值(举例):
void  无返回值
String 返回值是字符串类型
*    返回值任意
  • 包(举例):
com.xx.user.dao    固定包
com.xx.*.dao       com.xx下的任意包中的dao包
com.xx.user.dao..  包括dao下所有子包中
  • 类(举例):
UserDaoImpl  具体类
User*       以User开头类
*User       以User结尾类
*         任意类
  • 方法(举例):
addUser      具体方法
*        任意方法
*User      以add结尾方法
add*       以add开头方法

- 参数(无参):

()  无参
(..) 任意参数
(String, int) 1个String和1个int类型的参数
(int)  1个int类型参数
  • throws,可省略一般不写

通知类型

@Aspect
@Component
public class MyAspect {

    /**
     * 定义一个切入点表达式,表示需要应用的切入点
     */
    @Pointcut("execution(* org.example.aop.AopTarget.*(..))")
    public void firstJoinPoint() {
    }

    /**
     * 前置通知
     * @param joinPoint
     */
    @Before("firstJoinPoint()")
    public void before(JoinPoint joinPoint) {
        System.out.println("@Before前置通知");
    }

    /**
     * 后置通知
     * @param joinPoint
     * @param result
     */
    @AfterReturning(value = "firstJoinPoint()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("@AfterReturning后置通知结果为:" + result);
    }

    /**
     * 环绕通知
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("firstJoinPoint()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("@Around环绕通知=前");
        Object obj = joinPoint.proceed();
        System.out.println("@Around环绕通知=后");
        return obj;
    }

    /**
     * 异常抛出通知
     * @param e
     */
    @AfterThrowing(value = "firstJoinPoint()", throwing = "e")
    public void afterThrowing(Throwable e) {
        System.out.println("@AfterThrowing异常抛出通知" + e.getMessage());
    }

    /**
     * 最终通知
     */
    @After("firstJoinPoint()")
    public void after() {
        System.out.println("@After最终通知");
    }

    /**
     * 打印切点属性
     * @param joinPoint
     */
    private void printJoinPoint(JoinPoint joinPoint) {
        System.out.println("目标方法名为:" + joinPoint.getSignature().getName());
        System.out.println("目标方法所属类的简单类名:" + joinPoint.getSignature().getDeclaringType().getSimpleName());
        System.out.println("目标方法所属类的类名:" + joinPoint.getSignature().getDeclaringTypeName());
        System.out.println("目标方法声明类型:" + Modifier.toString(joinPoint.getSignature().getModifiers()));
        // 获取传入目标方法的参数
        Object[] args = joinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            System.out.println("第" + (i + 1) + "个参数为:" + args[i]);
        }
        System.out.println("被代理的对象:" + joinPoint.getTarget());
        System.out.println("代理对象自己:" + joinPoint.getThis());
    }
}
上一篇:go sqlit3使用一


下一篇:子类化SurfaceView并重写onDraw()以更改SurfaceView参数以生成所需大小的预览