ssm 学习笔记 day02
AOP静态处理
现在我们编写一个加减乘除的组件(Bean)
package com.atguigu.spring02aop.calculator.impl;import com.atguigu.spring02aop.calculator.MathCalculator;
import org.springframework.stereotype.Component;@Component
public class MathCalculatorImpl implements MathCalculator {@Overridepublic int add(int a, int b) {return a + b;}@Overridepublic int sub(int a, int b) {return a - b;}@Overridepublic int div(int a, int b) {return a / b;}@Overridepublic int mul(int a, int b) {return a * b;}
}
现在我们开始静态代理,就是类似于@Aware注释,用接口把该组件变成自己的实例属性,然后方法就可以灵活使用改类的方法,从而编写一个log记录,因为类似于代理,所以一般称为静态代理。
package com.atguigu.spring02aop.proxy.statics;import com.atguigu.spring02aop.calculator.MathCalculator;
import jdk.jfr.DataAmount;
import lombok.Data;
import org.springframework.stereotype.Component;@Data
@Component
public class CalculatorStaticProxy implements MathCalculator {private MathCalculator target;public CalculatorStaticProxy(MathCalculator mc) {this.target = mc ;}@Overridepublic int add(int a, int b) {System.out.println("执行加法add a , b");int result = target.add(a, b);System.out.println("输出加法add a , b");return result;}@Overridepublic int sub(int a, int b) {System.out.println("执行减法sub a , b");int result = target.sub(a, b);System.out.println("输出减法sub a , b");return result;}@Overridepublic int div(int a, int b) {System.out.println("执行除法div a , b");int result = target.div(a, b);System.out.println("输出除法div a , b");return result;}@Overridepublic int mul(int a, int b) {System.out.println("执行乘法mul a , b");int result = target.mul(a, b);System.out.println("输出乘法mul a , b");return result;}
}
执行结果如下
AOP动态代理
使用以下函数实现动态代理
参数分别为,代理对象的加载器、接口,以及拦截器。
如果我们用这个代理去代理之前所说的MathCalculator对象,我们可以采取以下写法。
在拦截器中,method.invoke(target,args)表示放行。
动态代理的封装
AOP的定义
简单地来说,就是类似于对运行的启动、运行、返回结果、错误这四个流程插入了一个类似于检测器/拦截器,更类似于try catch finally之类的语法。
@Aspect
首先引入包
ps:引入这个包的时候出现了一直引入不进去的情况,上面说not found,很奇怪,然后我重启了一下Idea就加载进去了。
切入点表达式的格式
example
测试
通配符
*
表示所有
..
表示任意多个参数
最省略写法* *(..)
底层原理
JointPoint
切点,封装了当前保存的所有参数信息。
可以通过JointPoint获取方法名,参数信息,通过签名(里面存放了方法、参数)
也可以获得返回值,在注释中添加一个resulting对应的接受对象,如下图,用result来接收。
@PointCut
用法(标记定位点)
Around环绕通知
我认为环绕通知是最具体的、最底层的一个写法,基本上和我之前学的想法类似,就是在函数启动前加上一个切面,返回结果加上一个切面,最后结果加上一个切面,异常接收一个切面。分模块的好处就是模块化,低耦合,环绕可以更加灵活使用。
写法如下。