代理模式-静态代理-动态代理

代理模式:就是一个类的功能通过其他类调用实现,这个其他类就是代理。一般的用处就是在执行功能的时候,可以通过代理在功能执行的前后增加其他的功能。

需求场景:用户各种操作的日志的记录

静态代理:

        关系图:

        代码:

package proxy;
//静态代理
public class StaticProxy {
    public static void main(String[] args) {
        OperationProxy operationProxy = new OperationProxy();
        operationProxy.login();
        /**
         * 操作之前记录日志
         * 晓峰进行了登录
         * 操作之后记录日志
         */
    }
}

//操作
abstract class Operation {
    abstract public void login();
    abstract public void logout();
    abstract public void order();
}

//真实的操作
class RealOperation extends Operation{
    public void login() {
        System.out.println("晓峰进行了登录");
    }
    public void logout() {
        System.out.println("晓峰进行了退出");
    }
    public void order() {
        System.out.println("晓峰进行了下单");
    }
}

//代理类
class OperationProxy {
    RealOperation realOperation;
    public OperationProxy() {
        this.realOperation = new RealOperation();
    }
    public void login() {
        beforeLog();
        realOperation.login();
        afterLog();
    }
    public void logout() {
        beforeLog();
        realOperation.logout();
        afterLog();
    }
    public void order() {
        beforeLog();
        realOperation.order();
        afterLog();
    }
    private void beforeLog() {
        System.out.println("操作之前记录日志");
    }
    private void afterLog() {
        System.out.println("操作之后记录日志");
    }
}

这就是静态代理了,但是静态代理有个问题,就是如果每一个类中的每一个方法 都需要增加若干个相同功能,那岂不是每一个功能都需要设置代理,就像上面的代码,那就要疯掉了,所以需要一个实现一个东西,可以动态的给方法设置代理。动态的获取到执行的方法。这就是动态代理。

动态代理:

package proxy.dynamic;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxy {
    public static void main(String[] args) {
        //创建被代理的实例对象
        Operation realOperation = new RealOperation();
        //创建InvocationHandler对象
        OperationInvocationHandler operationHandler = new OperationInvocationHandler<Operation>(realOperation);

        //创建代理对象,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
        Operation realOperationProxy = (Operation) Proxy.newProxyInstance(Operation.class.getClassLoader(),new Class<?>[]{Operation.class}, operationHandler);
        realOperationProxy.login();

        //也可以使用下面的方式创建代理类对象,Proxy.newProxyInstance其实就是对下面代码的封装
		/*try {
			//使用Proxy类的getProxyClass静态方法生成一个动态代理类renterProxy
			Class<?> operationProxyClass = Proxy.getProxyClass(Operation.class.getClassLoader(), new Class<?>[]{Operation.class});
			//获取代理类renterProxy的构造器,参数为InvocationHandler
			Constructor<?> constructor = operationProxyClass.getConstructor(InvocationHandler.class);
			//使用构造器创建一个代理类实例对象
            Operation renterProxy = (Operation)constructor.newInstance(operationHandler);
			renterProxy.login();
		} catch (Exception e) {
			e.printStackTrace();
		}*/

        /**
         * 操作之前记录日志
         * 晓峰进行了登录
         * 操作之后记录日志
         */

    }
}
//操作
interface Operation {
    public void login();
    public void logout();
    public void order();
}

//真实的操作
class RealOperation implements Operation {
    public void login() {
        System.out.println("晓峰进行了登录");
    }
    public void logout() {
        System.out.println("晓峰进行了退出");
    }
    public void order() {
        System.out.println("晓峰进行了下单");
    }
}

//代理类
class OperationInvocationHandler<T> implements InvocationHandler {
    //被代理类的对象
    private T target;

    public OperationInvocationHandler(T target){
        this.target = target;
    }
    /**
     * proxy:代表动态代理对象
     * method:代表正在执行的方法
     * args:代表调用目标方法时传入的实参
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //代理过程中插入其他操作
        beforeLog();
        Object result = method.invoke(target, args);
        afterLog();
        return result;
    }

    private void beforeLog() {
        System.out.println("操作之前记录日志");
    }
    private void afterLog() {
        System.out.println("操作之后记录日志");
    }
}

这就是动态代理了,动态代理任何一个类的方法,当然这种方式有一个缺陷就是类必须需要实现接口,如果没有实现接口就无法用这种方式了(如果没有实现接口可以使用cglib的动态代理方式,原理是创建一个子类(静态代理类),然后创建调用)

原理:创建一个临时的类(这个类其实就是相当于一个静态代理的类),并将这个类放到内存中,通过反射创建对象,进行调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值