[设计模式]代理模式
代理模式PROXY
静态代理
定义一个代理规范,规定代理和目标对象实现同样的方法
举个例子,银行柜员和银行都要有取钱的方法,我们才能通过银行柜员去取银行的钱
public interface Proxy {
void withdraw();
}
public class Bank implements Proxy{
@Override
public void withdraw(){
System.out.println("银行正在为你取钱");
}
}
public class Stuff implements Proxy{
Bank bank;
@Override
public void withdraw() {
if(bank == null){
bank = new Bank();
}
System.out.println("银行柜员正在为你取钱");
bank.withdraw();
System.out.println("银行柜员取钱完成");
}
}
public class User {
public static void main(String[] args) {
Stuff stuff = new Stuff();
stuff.withdraw();
}
}
动态代理
首先我们编写一个目标类,也就是真正干活的类
public class TrainStation implements ProxyMethod {
public TrainStation() {
}
@Override
public void sellTicket() {
System.out.println("火车站正在出票");
}
@Override
public boolean refund() {
System.out.println("火车站正在退票");
return true;
}
}
然后定义一个接口,规定我们想要代理的方法
public interface ProxyMethod {
void sellTicket();
boolean refund();
}
编写代理工具类,负责生成代理对象
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
public static ProxyMethod creatProxy(TrainStation trainStation) {
ProxyMethod proxyMethod = (ProxyMethod) Proxy.newProxyInstance(
ProxyUtil.class.getClassLoader(),
new Class[]{ProxyMethod.class},
new InvocationHandler() {
@Override
// 当我们使用代理对象
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("sellTicket")) {
System.out.println("代理正在买票");
}
if (method.getName().equals("refund")) {
System.out.println("代理正在退票");
}
Object res = method.invoke(trainStation, args);
if (method.getName().equals("sellTicket")) {
System.out.println("代理正在出票");
}
if (method.getName().equals("refund")) {
System.out.println("代理正在退票");
}
return res;
}
});
return proxyMethod;
}
}
最后client测试
public class Client {
public static void main(String[] args) {
TrainStation trainStation = new TrainStation();
ProxyMethod p = ProxyUtil.creatProxy(trainStation);
p.sellTicket();
boolean b = p.refund();
System.out.println(b);
}
}
动态代理分为两种一种是jdk代理
JDK动态代理是Java标准库中提供的一种代理方式,它可以在运行时动态生成一个代理对象,代理对象实现和原始类一样的接口,并将方法调用转发给被代理对象,同时还可以在方法调用前后执行额外的增强处理。
JDK动态代理通过反射机制实现代理功能,其原理分为以下几个步骤:
创建实现InvocationHandler接口的代理类工厂:在调用Proxy类
的静态方法newProxyInstance
时,会动态生成一个代理类。该代理类实现了目标接口,并且持有一个InvocationHandler
类型的引用。
InvocationHandler接口:InvocationHandler是一个接口,它只有一个方法invoke
。在代理对象的方法被调用时,JVM会自动调用代理类的invoke
方法,并将被调用的方法名、参数等信息传递给该方法。
调用代理对象的方法:当代理对象的方法被调用时,JVM会自动调用代理类的invoke方法。在invoke方法中,可以根据需要执行各种逻辑,比如添加日志、性能统计、事务管理等。
invoke方法调用:在invoke方法中,通过反射机制调用目标对象的方法,并返回方法的返回值。在调用目标对象的方法前后,可以执行额外的逻辑。