博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅谈自己对于spring aop的理解
阅读量:4093 次
发布时间:2019-05-25

本文共 3913 字,大约阅读时间需要 13 分钟。

  • 开始学习spring就被重点的关注ioc和aop这两个关键的部分,今天着重了解下关于aop的一些实现和原理。
    • aop 面向切面编程 即可以在业务逻辑前后加上需要的无关业务的处理如日志,权限控制等操作,与实际的业务相分离。
    • 首先需要介绍的技术就是AspectJ 了解了这个之后会对spring的aop实现有对比显示出两者的差异。aspectJ是一个由java实现的aop框架,通过对编译期的代码进行编译 让代码具有aop的功能。
      • 切面就是切点与通知的一个组合,在切面内部定义了两个部分
        • 切点 pointcut 即需要应用切面的方法,
        • pointcut 函数名 call(){匹配表达式}
        • pointcut recordLog():call(* HelloWord.sayHello(..));
        • 通知 advice 需要在目标方法前后执行的函数
          • before 前置通知 目标方法执行前
          • after 后置通知 目标方法执行后
          • after returning 方法返回通知 目标方法返回时执行
          • after throwing 异常通知 目标方法抛出异常时执行
          • around 目标函数中 执行 可以控制目标函数是否执行 环绕通知
        • 目标函数 称为连接点 joinPoint
        • 织入 指代码切入到目标函数的过程 例如aspectJ到java程序的过程称为织人
          • 静态织入 aspectJ 编译为class文件后在目标类中织入
            • idea进行aspectJ
          • 动态织入 jdk动态代理 cglib
            • @Aspect
@Aspectpublic class AspectJ {
/** * 前置通知 */ @Before("execution(* aop.UserDao.addUser(..))") public void before(){ System.out.println("前置通知"); } /** * 后置通知 * returnVal,切点方法执行后的返回值 */ @AfterReturning(value="execution(* aop.UserDao.addUser(..))",returning = "returnVal") public void AfterReturning(Object returnVal){ System.out.println("后置通知...."+returnVal); } /** * 环绕通知 * @param joinPoint 可用于执行切点的类 * @return * @throws Throwable */ @Around(value="execution(* aop.UserDao.addUser(..))") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕前....."); Object result = joinPoint.proceed(); System.out.println("环绕后....."); return result; } /** * 抛出通知 * @param e */ @AfterThrowing(value = "execution(* aop.UserDao.addUser(..))",throwing = "e") public void afterThrowable(Throwable e){ System.out.println("出现异常:msg="+e.getMessage()); } /** * 无论什么时候都会执行 */ @After(value = "execution(* aop.UserDao.addUser(..))") public void after(){ System.out.println("最终通知...."); }}或者@Pointcut(value = "execution( * aop.UserDao.addUser(..))")public void p1(){}/** * 前置通知 */@Before(value = "p1()")public void before(){ System.out.println("前置通知");}
  • 切点指示符
.. 匹配方法中任意参数数量的方法within(com.zejian.dao..*) 匹配该类中的所有方法within(com.zejian.dao.DaoUser+) 匹配该类的所有子类/实现该接口的类的所有方法within(com.zejian.service..*) 匹配 该包及子包下的所有方法类型签名表达式within(
)方法签名表达式//匹配UserDaoImpl类中的所有方法 @Pointcut("execution(* com.zejian.dao.UserDaoImpl.*(..))") //匹配UserDaoImpl类中的所有公共的方法 @Pointcut("execution(public * com.zejian.dao.UserDaoImpl.*(..))") //匹配UserDaoImpl类中的所有公共方法并且返回值为int类型 @Pointcut("execution(public int com.zejian.dao.UserDaoImpl.*(..))") //匹配UserDaoImpl类中第一个参数为int类型的所有公共的方法 @Pointcut("execution(public * com.zejian.dao.UserDaoImpl.*(int , ..))")bean@Pointcut("bean(*Service)") 用于匹配后缀为service的bean private void myPointcut1(){}this 用于匹配当前AOP代理对象类型的执行方法and or not ! && ||

Aspect的优先级

  • 不同切面

    • 实现 ordered接口 实现getOrder() 越小的优先级越高
    • 基于注解的 @Order(0,1,2)

      AOP的应用场景

      • 模拟系统性能监控
      • 异常统计

        实现原理

      • cglib 继承

        • interface methodInterceptor
        • Enhancer 产生代理对象(被代理对象的子类)
      • jdk动态代理 基于反射

附上代码

public class CglibProxy implements MethodInterceptor {
//被代理对象 private A target; public CglibProxy(A target) { super(); this.target = target; } public A createProxy(){ // 1.声明增强类实例,用于生产代理类 Enhancer enhancer = new Enhancer(); // 2.设置被代理类字节码,CGLIB根据字节码生成被代理类的子类 enhancer.setSuperclass(target.getClass()); // 3.设置回调函数 enhancer.setCallback(this); // 创建代理 return (A) enhancer.create(); } /** * 回调函数 */ @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { if("execute".equals(method.getName())) { //调用前验证权限(动态添加其他要执行业务) // AuthCheck.authCheck(); //调用目标对象的方法(执行A对象即被代理对象的execute方法) Object result = methodProxy.invokeSuper(proxy, args); //记录日志数据(动态添加其他要执行业务) // Report.recordLog(); return result; } return methodProxy.invokeSuper(proxy,args); }}

参考博客

转载地址:http://mqiii.baihongyu.com/

你可能感兴趣的文章
React + TypeScript 实现泛型组件
查看>>
TypeScript 完全手册
查看>>
React Native之原理浅析
查看>>
Git操作清单
查看>>
基础算法
查看>>
前端面试
查看>>
react 设置代理(proxy) 实现跨域请求
查看>>
通过试题理解JavaScript
查看>>
webpack的面试题总结
查看>>
实践这一次,彻底搞懂浏览器缓存机制
查看>>
Koa2教程(常用中间件篇)
查看>>
React Hooks 完全指南
查看>>
nvm 和 nrm 的安装与使用
查看>>
PM2 入门
查看>>
Flutter Animation动画
查看>>
Flutter混合开发二-FlutterBoost使用介绍
查看>>
Flutter 混合开发框架模式探索
查看>>
Flutter 核心原理与混合开发模式
查看>>
Flutter Boost的router管理
查看>>
Android Flutter混合编译
查看>>