AOP

  • 1. 什么是AOP
  • 2. AOP常用注解
  • 3.Spring4各种通知的执行节点
  • 4. 在aop中校验不通过如何不让程序进入核心代码?
  • 5. 同一个方法被多个Aspect类拦截
    • 5.1 如何指定每个 aspect 的执行顺序呢?
    • 注意:
  • 6. AOP应用:
    • 6.1 创建目标对象类
    • 6.2 切面
    • 6.3 测试前置通知
    • 6.4 返回通知、异常通知、后置通知
    • 6.5 环绕通知
  • 7. Spring4和Spring5的区别:
  • 8.动态代理静态代理

1. 什么是AOP

AOP:能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用 JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 Cglib 生成一个被代理对象的子类来作为代理,如下图所示:

2. AOP常用注解

@Component
@Aspect  //@Aspect 表示它是一个切面。
public class DemoAspect {//配置切入点 @Pointcut("execution(* com.aop.service.*.*(..))")public void myPointCut () {}//配置前置通知@Before("myPointCut()")public void myBefore () {System.out.println("——————前置通知————");}//*returning为连接点的返回值,命名须与myAfterReturning()方法的Object参数一致。@AfterReturning(pointcut = "myPointCut()", returning = "obj")public void myAfterReturning (JoinPoint point, Object obj) {System.out.println("——————返回通知————");//获取连接点方法传入的实参Object[] args = point.getArgs();//获取连接点方法的方法名String methodName = point.getSignature().getName();//获取连接点方法所在的对象Object targetObj = point.getTarget();String targetClassName = point.getClass().getName();}@AfterThrowing(pointcut = "myPointCut()", throwing = "eeeee")public void myAfterThrowing (JoinPoint point, Exception eeeee) {//注意那串eeeee了吗,那是为了引起你的注意,告诉你这两个命名须一致。System.out.println("——————异常通知————" + eeeee.getMessage());}@After("myPointCut()")public void myAfter (JoinPoint point) {System.out.println("——————最终通知————" + point.getSignature().getName());}
}

3.Spring4各种通知的执行节点



*如果抛出异常,那@Around方法的后半部分就应该是不会执行的

4. 在aop中校验不通过如何不让程序进入核心代码?

通过aop中注解的执行的先后顺序我们知道,校验发生在核心代码前面的只剩下两个——@Before,@Around。
@Before : 这个注解只有在异常时才不会走核心方法——连接点。正常@Before无法阻止当前线程进入连接点。
@Around : 这个注解在连接点前后执行。并且注解的方法传入的ProceedingJionPoint 类中封装的代理方法proceed()可以让当前线程从aop方法转到连接点——核心代码方法。所以一般我们用这个注解,如果aop的安全校验不通过,则不调用proceed()方法,就永远不会进入连接点。
除此外,要注意除了Around注解的方法可以传ProceedingJionPoint 外,别的几个都不能传这个类。

5. 同一个方法被多个Aspect类拦截

aspect1 和 aspect2 的执行顺序是未知的。

5.1 如何指定每个 aspect 的执行顺序呢?

给aspect添加@Order注解,该注解全称为:org.springframework.core.annotation.Order

@Order(5)
@Component
@Aspect
public class Aspect1 {// ...
}@Order(6)
@Component
@Aspect
public class Aspect2 {// ...
}

这样修改之后,可保证不管在任何情况下, aspect1 中的 advice 总是比 aspect2 中的 advice 先执行。如下图所示:

注意:

  • 如果在同一个 aspect 类中,针对同一个 pointcut,定义了两个相同的 advice(比如,定义了两个@Before),那么这两个 advice 的执行顺序是无法确定的,哪怕你给这两个 advice 添加了@Order这个注解,也不行。这点切记。

  • 对于@Around这个advice,不管它有没有返回值,但是必须要方法内部,调用一下pjp.proceed();否则,Controller 中的接口将没有机会被执行,从而也导致了
    @Before这个advice不会被触发。比如,我们假设正常情况下,执行顺序为”aspect2 -> apsect1 ->controller”,如果,我们把 aspect1中的@Around中的
    pjp.proceed();给删掉,那么,我们看到的输出结果将是:

6. AOP应用:

6.1 创建目标对象类

public interface IService {String update(String msg);
}@Service
public class IServiceImpl implements IService {@Overridepublic String update(int uid, String msg) {System.out.println("serviceimpl运行了");     return "更新了数据:"+msg;}
}

6.2 切面

@Component
@Aspect  //@Aspect 表示它是一个切面。
public class DemoAspect {//配置切入点 @Pointcut("execution(* com.aop.service.*.*(..))")public void myPointCut() {}//配置前置通知@Before("myPointCut()")public void myBefore() {System.out.println("——————前置通知————");}
}

@Pointcut("execution("result range")
Pointcut注解有两个参数,result是返回值的类型 , range是指定范围来配置通知的类,两个参数用空格隔开
在演示代码中,我是用的 * com.aop.service..(…)),意义如下。

@Pointcut("execution(任意返回值     com包.aop包.service包.所有类.所有方法(任意参数))")
//其中返回值、包、类、方法的通配符为 *
//参数的通配符为 ..

6.3 测试前置通知

public class Test {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");IService ser=ac.getBean(IService.class);   //update方法只是返回了这段字符串,所以并不会打印。ser.update("测试字符串");}
}

6.4 返回通知、异常通知、后置通知

//*returning为连接点的返回值,命名须与myAfterReturning()方法的Object参数一致。
@AfterReturning(pointcut="myPointCut()",returning="obj")
public void myAfterReturning(JoinPoint point,Object obj) {System.out.println("——————返回通知————");//获取连接点方法传入的实参Object[] args=point.getArgs();//获取连接点方法的方法名String methodName=point.getSignature().getName();//获取连接点方法所在的对象Object targetObj=point.getTarget();String targetClassName=point.getClass().getName();
}@AfterThrowing(pointcut="myPointCut()",throwing="eeeee")
public void myAfterThrowing(JoinPoint point,Exception eeeee) {//注意那串eeeee了吗,那是为了引起你的注意,告诉你这两个命名须一致。System.out.println("——————异常通知————"+eeeee.getMessage());
}@After("myPointCut()")
public void myAfter(JoinPoint point) {System.out.println("——————最终通知————"+point.getSignature().getName());
}

spring5执行结果:

6.5 环绕通知

*环绕通知的返回值必须是Object,形参必须是ProceedingJoingPoint。

@Component
@Aspect
public class DemoAspect {//配置切入点
@Pointcut("execution(* com.aop.service.*.*(..))")
public void myPointCut() {}
//环绕通知
@Around("myPointCut()")
public Object aroundAdvice(ProceedingJoinPoint proceeding) {//和JoinPoint一样,ProceedingJoinPoint也可以获取//连接点方法的实参Object[] args=proceeding.getArgs();//连接点方法的方法名String methodName=proceeding.getSignature().getName();//连接点方法所在的对象Object targetObj=proceeding.getTarget();String targetClassName=targetObj.getClass().getName();Object result=null;try {System.out.println("前置通知====");//执行连接点的方法 获取返回值result=proceeding.proceed(args);System.out.println("返回通知====");}catch (Throwable e) {System.out.println("异常通知===");}finally {System.out.println("最终通知===");} return result;
}

Spring5运行结果:

7. Spring4和Spring5的区别:

Springboot1.X底层应用的是Spring4
Springboot2.X底层应用的是Spring5
当系统应用升级,应该考虑一下以下变更。

8.动态代理静态代理

对静态代理、JDK动态代理、CGLib动态代理做一个总结,静态代理的维护成本比较高,有一个被代理类就需要创建一个代理类,而且需要实现相同的接口。JDK动态代理模式和CGLib动态代理的区别是JDK动态代理需要被代理类实现接口,而CGLib则是生成被代理类的子类,要求被代理类不能是final的,因为final类无法被继承。

动态代理总结:https://www.cnblogs.com/teach/p/10763845.html
参考链接:https://blog.csdn.net/rainbow702/article/details/52185827
参考链接:https://blog.csdn.net/zhanglf02/article/details/78132304
示例参考:https://blog.csdn.net/saltsoul/article/details/93140707
更多详细案例:https://www.cnblogs.com/joy99/p/10941543.html

【Spring】AOP面向切面编程(Spring4和Spring5区别)相关推荐

  1. Java绝地求生—Spring AOP面向切面编程

    Java绝地求生-Spring AOP面向切面编程 背景 动态代理 构建被代理对象 自动生成代理 调用动态代理 Spring方法 方式一:使用Spring的API接口 方式二:使用自定义类 方式三:使 ...

  2. Spring AOP面向切面编程

    AOP面向切面编程: AOP(Aspect Oriented Programming),即面向切面编程,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公 ...

  3. Spring AOP 面向切面编程相关注解

    Aspect Oriented Programming 面向切面编程 在Spring中使用这些面向切面相关的注解可以结合使用aspectJ,aspectJ是专门搞动态代理技术的,所以比较专业. 需要在 ...

  4. Spring Aop面向切面编程自动注入

    1.面向切面编程 在程序原有纵向执行流程中,针对某一个或某一些方法添加通知,形成横切面的过程叫做面向切面编程 2.常用概念 原有功能:切点,pointcut 前置通知:在切点之前执行的功能,befor ...

  5. Spring AOP 面向切面编程

    AOP 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件 ...

  6. Spring AOP(面向切面编程)

    AOP(Aspect Oriented Programming),也就是面向切面编程,作为面向对象编程的一种补充,AOP已经成为一种比较成熟的编程方式.可以这样理解:OOP是从静态角度考虑程序结构,而 ...

  7. java框架013——Spring AOP面向切面编程

    一.Spring AOP简介 AOP的全称是Aspect-Oriented Programming,即面向切面编程(也称面向方面编程).它是面向对象编程(OOP)的一种补充,目前已成为一种比较成熟的编 ...

  8. JavaEE——Spring AOP(面向切面编程)

    目录 1.面向切面编程(AOP) 2.AOP术语 3.AOP类型 4.AOP 的优势 5.Spring AOP 的代理机制 6.Spring AOP 连接点 7.Spring AOP 通知类型 8.基 ...

  9. Spring AOP面向切面编程:理解篇(一看就明白)

    一直想着怎么去通俗的讲解AOP,看了一篇文章受到了启发(https://blog.csdn.net/qukaiwei/article/details/50367761),下面我加入自己的理解,咱们来说 ...

  10. Spring aop面向切面编程概述

    aop概述 1.AOP为Aspect Oriented Programming的缩写,意为:面向切面编程.将程序中公用代码进行抽离,通过动态代理实现程序功能的统一维护的一种技术.使代码耦合性降低,提高 ...

最新文章

  1. java 捕获异常并存入数据库_java异常处理,报异常的话怎么处理对象值,并持久化到数据库中...
  2. 设置按钮不可见_华为手机居然有【3种录屏方法】,很多人都不知道,真的太实用了...
  3. DPDK support for vhost-user(十四)
  4. lambdafiltermapreduce函数的基本使用
  5. android view取坐标点,Android 获取子 View 的位置及坐标的方式
  6. springboot通过url访问项目外的其他目录下的图片
  7. jzoj1753-锻炼身体【单调队列】
  8. python向空列表添加列表_Python列表核心知识点汇总
  9. Android开发:Handler Runnable和Thread之间的区别和联系 应用--------------------看完本篇,从此一览无余!...
  10. 物联网操作系统 - Contiki
  11. 自动化脚本任务计划程序(Windows)
  12. Java、JSP教务排课系统
  13. UTF-8与GBK字符之间的转换
  14. 一步一步实现iOS微信自动抢红包(非越狱)
  15. Electron应用-云桌面客户端
  16. HP笔记本电源灯亮不能开机 - 静电问题
  17. NETDMIS5.0笛卡尔坐标系和矢量2023
  18. HTML制作宣传片,怎么制作视频宣传片 视频宣传片制作软件 照片制作成宣传视频,并添加相关文字说明...
  19. 【深度学习】Pytorch实现CIFAR10图像分类任务测试集准确率达95%
  20. VS报错:“创建空文档失败”

热门文章

  1. Xshell基本命令指南
  2. 进制转换(二进制,八进制,十进制,十六进制)
  3. 蚂蚁森林至善林合种群二维码,靠谱合种组织
  4. CSS 实现自适应宽高的正圆
  5. jQuery form插件的使用
  6. vue项目高度未占满全屏,可以给app.vue页面设置样式,来让高度撑开全屏
  7. 数据库orcle-实验一 数据定义和数据更新
  8. 从技术角度分析,为什么ETH PoW分叉不具备正统性?
  9. chrome浏览器设置广告拦截器-Adblock Plus
  10. Java毕设项目滁州市住房公积金管理中心网站计算机(附源码+系统+数据库+LW)