4.1、概念
-
代理模式是二十三种设计模式中的一种,属于结构型模式
-
它的思想就是在不改动目标方法代码的基础上,增强目标方法的功能
-
它的实现就是通过提供一个代理类,让我们在调用目标方法的时候,不再是直接对目标方法进行调用,而是通过代理类间接调用目标方法
-
它的作用就是把不属于目标方法核心逻辑的代码从目标方法中剥离出来,从而实现解耦和统一维护
9.4.2、术语
9.4.3、生活中的目标和代理
9.5、静态代理
先将实现类CalculatorImpl还原为没有增加日志功能的状态,即9.2.1小节的状态
9.5.1、创建静态代理类CalculatorStaticProxy
注意:代理类和目标类要实现相同的接口,这样能保证它们有相同的方法列表
package org.rain.spring.proxy;
/**
* @author liaojy
* @date 2023/8/7 - 12:56
*/
public class CalculatorStaticProxy implements Calculator {
// 将被代理的目标对象声明为成员变量
private Calculator target;
public CalculatorStaticProxy(Calculator target) {
this.target = target;
}
public int add(int i, int j) {
// 附加功能由代理类中的代理方法来实现
System.out.println("[日志] add 方法开始了,参数是:" + i + "," + j);
// 通过目标对象来实现核心业务逻辑
int addResult = target.add(i, j);
System.out.println("[日志] add 方法结束了,结果是:" + addResult);
return addResult;
}
public int sub(int i, int j) {
System.out.println("[日志] sub 方法开始了,参数是:" + i + "," + j);
int subResult = target.sub(i, j);
System.out.println("[日志] sub 方法结束了,结果是:" + subResult);
return subResult;
}
public int mul(int i, int j) {
System.out.println("[日志] mul 方法开始了,参数是:" + i + "," + j);
int mulResult = target.mul(i, j);
System.out.println("[日志] mul 方法结束了,结果是:" + mulResult);
return mulResult;
}
public int div(int i, int j) {
System.out.println("[日志] div 方法开始了,参数是:" + i + "," + j);
int divResult = target.div(i, j);
System.out.println("[日志] div 方法结束了,结果是:" + divResult);
return divResult;
}
}
9.5.2、测试
package org.rain.spring.test;
import org.junit.Test;
import org.rain.spring.proxy.CalculatorImpl;
import org.rain.spring.proxy.CalculatorStaticProxy;
/**
* @author liaojy
* @date 2023/8/7 - 14:12
*/
public class ProxyTest {
@Test
public void testStaticProxy(){
CalculatorStaticProxy calculatorStaticProxy = new CalculatorStaticProxy(new CalculatorImpl());
int addResult = calculatorStaticProxy.add(1, 2);
System.out.println(addResult);
}
}
9.5.3、静态代理的缺点
9.6、动态代理
动态代理的意思是,在代码运行的过程中动态地生成目标类的代理类
9.6.1、创建生成代理对象的工厂类ProxyFactory
比起实现固定接口方法的静态代理,动态代理的关键是能动态获取并实现目标的接口方法;
因此动态代理能对任意目标对象的核心业务方法(接口方法)进行增强
package org.rain.spring.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
/**
* @author liaojy
* @date 2023/8/7 - 23:07
*/
//这个类不是一个代理类而是一个工具(工厂)类,用于动态生成目标对象的代理对象
public class ProxyFactory {
//因为被代理的目标对象是任意的,所以目标对象变量的类型设为Object
private Object target;
//通过工厂类的有参构造方法,对目标对象变量进行赋值
public ProxyFactory(Object target) {
this.target = target;
}
//生成任意目标对象所对应的代理对象;因为不确定动态生成的代理对象的类型,所以返回值设为Object
public Object getPoxy(){
//通过目标对象获取应用类加载器
ClassLoader classLoader = target.getClass().getClassLoader();
//获取目标对象实现的所有接口的class对象所组成的数组
Class<?>[] interfaces = target.getClass().getInterfaces();
//通过InvocationHandler的匿名内部类,来设置代理类中如何重写接口中的抽象方法
InvocationHandler invocationHandler = new InvocationHandler() {
//通过