作者:ColinYinbaohua | 来源:互联网 | 2023-05-18 22:58
AOP
- 面向切面编程 Aspects Oriented Programmer
- 正常程序执行流程都是纵向执行,面向切面编程是在原有纵向执行流程中,针对某一个或一些方法添加通知,形成横切面的过程
- 不需要修改原有的代码
- 高扩展性,原有功能相当于释放了部分逻辑,让职责更加明确
常用概念
- 原有功能:切点 pointcut
- 前置通知:在切点之前执行的功能 before advice
- 后置通知:在切点之后执行的功能 after advice
- 如果在切点执行过程中出现乙城,会触发异常通知 throws advice
Spring的两种实现AOP方式
- Schame-based
- 每个通知都要实现接口或类
- 配置 spring 配置文件时在 配置
- AspectJ
- 每个通知不需要实现接口或类
- 在 spring 配置文件 的子标签 中配置
Schema-based
public class MyBeforeAdvice implements MethodBeforeAdvice{@Overridepublic void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {System.out.println("执行前置方法!");}}
public class MyAfterAdvice implements AfterReturningAdvice{@Overridepublic void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {System.out.println("后置方法");System.out.println(arg0);System.out.println(arg1.getName());System.out.println(arg2);System.out.println(arg3);}}
public class Demo {public void demo1() {System.out.println("demo1");}public void demo2() {System.out.println("demo2");}public void demo3() {System.out.println("demo3");}public void demo4(String str) {System.out.println("demo4");}public String demo5(String str) {System.out.println("demo5");return str;}}
- spring 配置文件
- 引入 aop 命名空间
- 配置通知类的 bean
- 配置切面
<beans xmlns&#61;"http://www.springframework.org/schema/beans"xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance"xmlns:aop&#61;"http://www.springframework.org/schema/aop"xsi:schemaLocation&#61;"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id&#61;"mybefore" class&#61;"com.mak.advice.MyBeforeAdvice">bean><bean id&#61;"myafter" class&#61;"com.mak.advice.MyAfterAdvice">bean><aop:config><aop:pointcut expression&#61;"execution(* com.mak.test.Demo.demo2())" id&#61;"mypoint"/><aop:advisor advice-ref&#61;"mybefore" pointcut-ref&#61;"mypoint"/><aop:advisor advice-ref&#61;"myafter" pointcut-ref&#61;"mypoint"/>aop:config><bean id&#61;"demo" class&#61;"com.mak.test.Demo">bean>beans>
public class Test {public static void main(String[] args) {ApplicationContext ac &#61; new ClassPathXmlApplicationContext("applicationContext.xml");Demo demo &#61; ac.getBean("demo", Demo.class);demo.demo1();demo.demo2();demo.demo3();}}
demo1
执行前置方法&#xff01;
demo2 // 切点方法对象
[Ljava.lang.Object;&#64;71529963 // 切点方法参数
com.mak.test.Demo&#64;61a88b8c //切点所在类对象
demo2
后置方法
null // 切点方法返回值 demo2 没有返回值
demo2 // 七点方法对象
[Ljava.lang.Object;&#64;71529963 // 参数
com.mak.test.Demo&#64;61a88b8c // 所在类对象
demo3
通配符&#xff08;*&#xff09;的使用
<aop:pointcut expression&#61;"execution(* com.mak.test.Demo.*())" id&#61;"mypoint"/>
<aop:pointcut expression&#61;"execution(* com.mak.test.*.*())" id&#61;"mypoint"/>
<aop:pointcut expression&#61;"execution(* com.mak.test.*.*(..))" id&#61;"mypoint"/>