SpringAOP
SpringAOP是spring框架面向切面的编程思想。它补充了OOP的传统编程方法,通过构建独特的切面,实现对业务流程的控制。
SpringAOP依赖的jar包
通过SpringBoot的父级依赖,声明这是一个SpringBoot项目,它可以用来提供相关的Maven默认依赖。使用它之后,常用的包依赖可以省去version标签。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
此后配置spring-boot-starter-aop依赖就能顺滑地使用aop了!
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
AOP术语
概念 | 说明 |
---|---|
目标对象(Target Object) | 被一个或者多个切面所通知的对象,也被称作被通知对象 |
代理对象(Proxy Object) | AOP框架创建的对象,它和目标对象遵循同样的接口,使用它的方式和使用目标对象的方式是一样的,但是它是目标对象的增强版,“通知”中的代码执行将会被代理对象的方法调用触发。在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。 |
JDK动态代理开发
代理设计模式的原理: 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上。
测试类:
//接口类
public interface BankService {
public void transfer(String source, String target, BigDecimal money);
}
//接口实现类
public class XTBankService implements BankService{
public void transfer(String source, String target, BigDecimal money) {
System.out.println(source + "向" + target + "转账:" + money + "元。");
}
}
//代理类
public class ObjProxy implements InvocationHandler{
private Object target;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke方法被调用!");
System.out.println(method.getName() + "的参数:");
for(Object arg : args) {
System.out.println("====>" + arg);
}//遍历打印方法传递的参数
return method.invoke(target, args);
}
//通过creatProxy()方法获取代理对象
public Object creatProxy(Object target) {
this.target = target;
System.out.println("cteatProxy方法被调用!");
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
}
//测试类
public class Main {
public static void main(String[] args) {
BankService bs = new XTBankService();
BankService objProxy = (BankService) new ObjProxy().creatProxy(bs);//类型强转
System.out.println("-----------------------------------------------");
objProxy.transfer("A", "B", new BigDecimal("1999.0"));
}
}
测试结果:
cteatProxy方法被调用!
-----------------------------------------------
invoke方法被调用!
transfer的参数:
====>A
====>B
====>1999.0
A向B转账:1999.0元。