spring aop

news/2024/5/15 3:24:39

约定编程:我们只需要实现约定的流程部分,而具体实现通过框架实现

“约定编程”(Convention Over Configuration)是一种软件开发的理念,旨在减少开发者在项目配置上的决策,并通过约定促进开发者之间的协作和项目的一致性。

aop的约定执行流程:
请添加图片描述

AOP的具体实现过程(由框架实现)

有三个重要的对象,一个是被代理的类,一个是拦截器,一个是代理对象。

public interface HelloService{public void sayHello(String name);
}
//被代理对象
public class HelloServiceImpl implements HelloService{@Overridepublic void sayHello(String name){System.out.println("hello"+name);}
}
//拦截器接口
public interface Interceptor{public boolean before();public void after();public Object around(Invocation invocation);public void afterReturning();public void afterThrowing();boolean useAround();
}
执行被代理对象的方法的一个包装类
public class Invocation{private Object[] params;private Method method;private Object target;public Invocation(Object target,Method method,Object[] params){this.target=target;this.method=method;this.params=params;}public Object proceed(){return method.invoke(target,params);}
}
//拦截器的实现
public class MyInterceptor implements Interceptor{@Overridepublic boolean before(){;}@Overridepublic boolean useAround(){ return true;}@Overridepublic void after(){;}@Overridepublic void after(){;}@Overridepublic Object around(Invocation invocation){System.out.println("around before...");Object obj=invocation.proceed();System.out.println("around after...");return obj;}@Overridepublic void afterReturning(){;}@Overridepublic void afterThrowing(){;}
}
//实现aop约定编程的具体类
public class ProxyBean implements InvocationHandler{private Object target=null;//被代理对象private Interceptor interceptor=null;//拦截器@Overridepublic static Object getProxyBean(Object target,Interceptor interceptor){ProxyBean proxyBean = new ProxyBean();proxyBean.target = target;proxyBean.interceptor = interceptor;Object proxy=Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces().proxyBean);return proxy;//返回代理对象}@Overridepublic Object invoke(Object proxy,Method method,Object[] args){boolean exceptionFlag = false;Invocation invocation = new Invocation(target,method,args);this.interceptor.before();Object retObj = null;if(this.interceptor.useAround()){retObj=this.interceptor.around(invocation);elseretObj=method.invoke(target,args);return retObj;}

AOP

切点(Pointcut)在 AOP 中用于定义哪些连接点(Join Point)会被拦截器(Advice)所拦截。连接点是在程序执行过程中能够插入拦截器的点,比如方法调用、方法执行时异常抛出等。切点定义了一组连接点,这些连接点满足切点的条件,会被相应的拦截器所拦截。

所以,切点可以看作是一种匹配规则,它确定了哪些连接点会被织入(Weaving)到切面(Aspect)中。连接点是一个程序执行的具体位置,而切点则定义了应该在哪些具体位置执行拦截器中的逻辑。

切面(Aspect)

在 Spring 框架中,切面通常作为一个普通的 Java 类,并使用 @Aspect 注解进行标注。
在切面中,你可以定义一系列的通知(Advice)以及切点(Pointcut)。

通知(Advice)

通知是切面的具体行为。它定义了在程序执行的不同点上执行的代码。
Spring AOP 支持以下几种类型的通知:
前置通知(Before advice):在方法执行前执行。
后置通知(After returning advice):在方法执行后执行。
后置异常通知(After throwing advice):在方法抛出异常时执行。
后置最终通知(After finally advice):在方法执行后执行,无论方法是否抛出异常都会执行。
环绕通知(Around advice):在方法执行前后都执行,并且可以控制方法的执行。

切点(Pointcut):一个切面匹配的所有连接点都叫切点。

切点的主要功能就是简化连接点的定义和书写。
定义切点后,连接点想要织入切面,就将这个切面的连接点设置为切点,简化了开发。

可以只使用连接点而不使用切点。

切点定义了切面逻辑将被应用到哪些连接点(join points)上。
通过使用切点表达式(Pointcut expressions),可以精确地指定哪些方法、哪些类需要应用切面逻辑。

连接点(Join point)

连接点是在应用程序执行过程中可以插入切面的点,方法调用或异常抛出时。

引入(Introduction)

引入允许向现有类添加新方法或属性。在 Spring AOP 中,引入允许你向现有的类中添加新的接口实现。

目标对象(Target object)

目标对象是被代理的对象,它包含了切面逻辑所要应用的方法。

代理(Proxy)

代理是一个类,它包装了目标对象,并且可以截获对目标对象方法的调用,以便在调用前后执行切面逻辑。

织入(Weaving)

织入是将切面逻辑应用到目标对象的过程。织入可以在编译时、类加载时、运行时进行。

为什么要使用AOP?

减少重复工作,比如使用jdbc需要获得连接和statement,使用AOP可以简化这些过程。

定义切面

@Aspect
public class MyAspect{@Before("execution(*com.springboot.chapter4.aspect.service.impl.UserServiceImp.printUser(..))")//通过连接点接入public void befor(){}@After("execution(*com.springboot.chapter4.aspect.service.impl.UserServiceImp.printUser(..))")public void after(){}@AfterReturning("execution(*com.springboot.chapter4.aspect.service.impl.UserServiceImp.printUser(..))")public void returning(){}@AfterThrowing("execution(*com.springboot.chapter4.aspect.service.impl.UserServiceImp.printUser(..))")public void throwing(){}
}

定义切点

会使用excution()里的正则式去匹配使用切点的,为了简化开发,我们也可以在切面中定义一个切点,然后赋值给方法。

@Aspect
public class MyAspect{@Pointcut("execution(*com.springboot.chapter4.aspect.esrvice.impl.UserServiceImple.printUesr(..))")public void pointCut(){}@Before("pointCut()")//使用切点(定义了切点的方法名)作为通知的连接点public void before(){}@After("ponintCut()")public void after(){}
}

环绕通知

最强大的切面,不执行原方法,而是执行环绕通知的方法。

@Around("pointCut()")
public void around(ProceedingJoinPoint jp){System.out.println("around before..");jp.proceed();System.out.println("after..");
}

execution中的正则表达式

execution(*com.springboot.chapter4.aspect.service.impl.UserServiceImpl.printUser(…))
*表示返回类型,(…)表示可以进行任意参数匹配

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.tangninghui.cn.cn/item-12907.htm

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Python | 超前滞后分析

Nino SST Indices (Nino 12, 3, 3.4, 4; ONI and TNI) 有几个指标用于监测热带太平洋,所有这些指标都是基于海表温度(SST)异常在一个给定的区域的平均值。通常,异常是相对于30年的周期来计算的。厄尔尼诺3.4指数(Nio 3.4 index)和海洋厄尔尼诺指数(Ocea…

酷开科技 |酷开系统全视频化升级,让电视回归视频属性

随着消费升级浪潮的兴起,家庭互联网这一概念也在资本的注入下,成为了新风口。酷开系统全视频化升级,让电视回归视频属性,酷开系统在之前瀑布流板块设计的基础上,增加了视频流图文融合的并行界面,同时酷开系…

【XCPC笔记】2023 (ICPC) Jiangxi Provincial Contest——ABCHIJKL 做题记录

赛后gym练习及补题,gym链接:2023 (ICPC) Jiangxi Provincial Contest – Official Contest 补题顺序 L [Zhang Fei Threading Needles - Thick with Fine](https://codeforces.com/gym/104385/problem/L)题面解读参考代码 A [Drill Wood to Make Fire](h…

【自控笔记】线性系统时域分析法

动态稳态性能 一阶系统 二阶系统 二阶系统单位阶跃 系统稳定性分析

Golang | Leetcode Golang题解之第9题回文数

题目&#xff1a; 题解&#xff1a; func isPalindrome(x int) bool {// 特殊情况&#xff1a;// 如上所述&#xff0c;当 x < 0 时&#xff0c;x 不是回文数。// 同样地&#xff0c;如果数字的最后一位是 0&#xff0c;为了使该数字为回文&#xff0c;// 则其第一位数字也…

C++从入门到精通——类对象模型

类对象模型 前言一、如何计算类对象的大小问题 二、类对象的存储方式猜测对象中包含类的各个成员代码只保存一份&#xff0c;在对象中保存存放代码的地址只保存成员变量&#xff0c;成员函数存放在公共的代码段问题总结 三、结构体内存对齐规则四、例题结构体怎么对齐&#xff…