前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring的AOP面向切面 知识点速查

Spring的AOP面向切面 知识点速查

作者头像
linxinzhe
发布2018-07-25 10:38:18
5010
发布2018-07-25 10:38:18
举报
文章被收录于专栏:林欣哲林欣哲林欣哲

AOP在Spring中原理

通过实现BeanPostProcessor接口的postProcessBeforeInitialization和postProcessAfterInitialization方法,在初始化前后用代理对象加强原来的类

实现方式

  • 预编译:AspectJ
  • 运行期动态代理(JDK动态代理、CGLib动态代理):SpringAOP、JbossAOP
AOP的相关术语
  • jointpoint(连接点):是指那些被拦截到的点。在spring中是指方法,因为spring只支持方法类型的连接点。
  • pointcut(切入点):对哪些joinpoint进行拦截
  • advice(通知/增强):拦截到的jionpoint所做的事情。方法层面的。
    • 前置通知
    • 后置通知
    • 异常通知(抛出异常)
    • 最终通知(无论如何都执行)
    • 环绕通知(方法执行的前后都通知,甚至可以阻止目标方法执行)
  • introduction(引介):特殊的通知,类层面的。
  • target(目标对象):代理的目标对象
  • weaving(织入):把增强应用到目标对象来创建新的代理对象的过程
  • proxy(代理):被AOP织入增强后产生的结果代理类
  • aspect(切面):切入点+通知的结合
    • advisor:一般的切面,advice本身就是一个切面,对目标类所有方法进行拦截
    • PointcutAdvisor:代表具有切点的切面,可以指定拦截目标类哪些方法
    • IntroductionAdvisor:引介切面
底层实现
  • JDK动态代理:对接口做动态代理。代理类继承InvocationHandler接口使用Proxy.newProxyInstance(被代理的接口)
  • CGLIB的动态代理:对实现类做子类增强。使用Enhancer增强
总结
  • spring在运行期间,生成动态代理对象,不需要特殊的编译器
  • spring AOP的底层是通过JDK动态代理或CGLib动态代理技术为目标Bean执行横向织入
    • 若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理
    • 若目标对象没有实现任何接口,spring使用CGLib库生成目标对象的子类
  • 程序中优先对接口创建代理,便于程序解耦维护
  • 标记为final的方法,不能被代理,因为无法进行覆盖
    • JDK动态代理,是针对接口生成子类,接口中方法不能使用final修饰
    • CGLib是针对目标类生产子类,因此类或方法不能使用final
  • spring只支持方法的连接点,不提供属性的连接点

AspectJ用法

通知类型
  • @Before 前置通知
  • @AfterReturning 后置通知
  • @Around 环绕通知
  • @AfterThrowing 异常抛出通知
  • @After 最终final通知
切入点表达式

语法: execution(<访问修饰符>? <返回类型> <方法名>(<参数>) <异常>) 举例:

  • 匹配所有类public方法 execution(public * *(..))
  • 匹配指定包下所有类方法 execution(* top.linxz.dao.(..)) 不包含字包
    • 包含子包execution( top.linxz.dao..(..)) ..表示包、子孙包下所有类
  • 匹配指定类所有方法 execution(* top.linxz.service.UserService.*(..))
  • 匹配实现特定接口所有类方法execution(* top.linxz.dao.GenericDAO+.*(..))
  • 匹配所有save开头的方法 execution(* save*(..))
通知的使用
  • 配置Aspect
@Aspect
public class MyAspectAnno{
    ...
}
  • 前置通知
@Before(value="execution(* top.linxz.java.UserDao(..))")
public void before(JoinPoint joinPoint){
    //joinPoint就是切到的方法
}
  • 后置通知
@AfterReturning(value="execution(* top.linxz.java.UserDao(..))", returning="returning")
public void afterReturing(Object returning){
    //这个returning就是拿到的返回值
}
  • 环绕通知
@Around(value="execution(* top.linxz.java.UserDao(..))", returning="returning")
public Object afterReturing(ProceedingJoinPoint joinPoint){
    System.out.println("环绕前通知")
    Object obj=joinPoint.proceed();//执行目标方法,如果不调用,目标方法就被拦截了。
    System.out.println("环绕后通知")
    return obj;
}
  • 异常通知
@AfterThrowing(value="execution(* top.linxz.java.UserDao(..))",throwing="e")
public void afterThrowing(Throwable e){

}
  • 最终通知,无论如何即使有异常也执行
@After(value="execution(* top.linxz.java.UserDao(..))")
public void afterThrowing(Throwable e){

}
  • @Pointcut为切点命名
    • 切点方法必须为private void 无参数方法,方法名为切点名
    • 当通知多个切点时,可以使用||进行连接

参考

  1. Spring AOP,https://class.imooc.com/course/587
  2. 基于AspectJ的AOP开发,https://class.imooc.com/course/588
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 林欣哲 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • AOP在Spring中原理
    • AOP的相关术语
      • 底层实现
        • 总结
        • AspectJ用法
          • 通知类型
            • 切入点表达式
              • 通知的使用
              • 参考
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档