0
点赞
收藏
分享

微信扫一扫

Spring学习(7) AOP前奏之代理模式


  • ​​代理模式​​
  • ​​为什么需要代理​​
  • ​​手动实现动态代理环境搭建​​
  • ​​手动实现动态代理关键步骤​​

代理模式

  • 代理模式:我们需要去做一件事情,但是又不希望自己去做,这个时候就可以找个代理(中介)
  • 我们(目标对象)与中介(代理对象)不能互相转换,因为是兄弟关系
  • Spring学习(7) AOP前奏之代理模式_动态代理

为什么需要代理

  • 需求:实现加减乘除的计算器类
  • 在加减乘除方法中,添加日志功能(在计算之前,记录日志,在计算之后,显示结果)
  • Spring学习(7) AOP前奏之代理模式_动态代理_02

  • 实现后发现的问题:
  • 日志代码比较分散,我们可以提取日志类
  • 日志代码比较混乱,日志代码(非核心代码)和加减乘除方法(核心代码)可以写在一处
  • 总结:在核心代码中,需要日志功能,但是我们并不希望,在核心代码中添加日志代码
  • 此时:我们可以使用代理模式来解决这个问题,先把日志代码横向提取在日志类中, 然后再动态织入回到业务代码中
  • Spring学习(7) AOP前奏之代理模式_目标对象_03

手动实现动态代理环境搭建

  • 实现方式
  • 基于接口实现动态代理:JDK动态代理
  • 基于继承实现动态代理:Cglib、Javassist动态代理
  • 实现动态代理关键步骤
  • 一个类:Proxy
  • 概述:Proxy代理类的基类(类似Object)
  • 作用:newProxyInstance():创建代理对象
  • 一个接口:InvocationHandler
  • 概述:实现动态织入效果的关键接口
  • 作用:invoke(),执行invoke()方法实现动态织入效果

手动实现动态代理关键步骤

  • 创建类(为了实现创建代理对象的工具类)
  • 提供属性(本质上是目标对象,在实现类中实现)
  • 提供方法(创建代理对象)
  • 提供有参构造器(为了避免目标对象为空)

接口

public interface Calc {
int add(int a, int b);

int sub(int a, int b);

int mul(int a, int b);

int div(int a, int b);
}

实现类

@Component
public class CalcImpl implements Calc{
@Override
public int add(int a, int b) {
int result=a+b;
return result;
}

@Override
public int sub(int a, int b) {
int result=a-b;
return result;
}

@Override
public int mul(int a, int b) {
int result= a*b;
return result;
}

@Override
public int div(int a, int b) {
int result= a/b;
return result;
}
}

日志

public class MyLogging {
public static void beforeMethod(String methodName,Object[]args){
System.out.println("==>Calc中"+methodName+"方法(),参数:"+ Arrays.toString(args));

}
public static void afterMethod(String methodName,Object res){
System.out.println("==>Calc中"+methodName+"方法(),结果:"+ res);
}


}

关键代码

**我们要获得代理对象,前提要知道代理谁
* @author zengyihong
* @create 2022--07--02 17:18
*/
public class MyProxy {
/**
* 目标对象
*/
private Object target;
public MyProxy(Object target){
this.target=target;
}

/**
* 获取目标对象的代理对象
* ClassLoader loader, 类加载器,用目标对象的类加载器
* Class<?>[] interfaces, 目标对象实现的所有接口
* InvocationHandler h
*/
public Object getProxyObject(){
//代理对象
Object proxyObj=null;
ClassLoader classLoader = target.getClass().getClassLoader();
Class<?>[] interfaces = target.getClass().getInterfaces();
//创建代理对象
proxyObj =Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行之前添加日志
MyLogging.beforeMethod(method.getName(),args);
//触发目标对象的目标方法 执行哪个目标对象的方法,方法参数
Object res = method.invoke(target, args);
//执行目标方法后,添加日志
MyLogging.afterMethod(method.getName(),res);
return res;
}
});
return proxyObj;
}





}

Spring学习(7) AOP前奏之代理模式_代理模式_04


举报

相关推荐

0 条评论