在很多框架中,代理模式使用的比较多,在学习mybatis源码过程中大量用到代理模式。今天复习一下几种代理模式:**静态代理**和**动态代理**
代理模式就相当于一个中介,比如房产中介,婚庆公司,它本身并没有实现房产,但是他代理了房产。
优点:
1.具有高扩展性(因为中间插入了中间层,可以对原有功能进行扩展)
2.职责清晰。
缺点:由于增加了中间层,可能导致处理效率变慢
***第一种情况:静态代理***
```javapackage com.study.mybatis;public class ProxyDemo {public static void main(String[] args) {Proxy proxy = new Proxy();proxy.say();}}//需要实现的功能interface Function{public void say();}//被代理的对象class ReallyClass implements Function{public void say(){System.out.println("我是被代理的类");}}//代理类class Proxy implements Function{private ReallyClass reallyClass;public void say(){if(reallyClass==null){reallyClass = new ReallyClass();}System.out.println("Proxy:");//在目标的业务代码前后可以任意插入别的业务/** 类似于,房东让中介代理房子,中介随便进行标价并且插入很多不相关的费用* */reallyClass.say();}//也可以在原有功能上对功能进行进一步扩展public void call(){System.out.println("我要打电话");}}```
***第二种情况:动态代理***
常见的动态代理用到的主要是:JDK动态代理和CGLib动态代理
这里主要对JDK动态代理进行解析。
JDK动态代理主要是**通过Java反射机制动态创建代理对象**。java.lang.reflect包,最好自己看一下API或者源码理清楚。
测试案例
```javapackage com.study.mybatis;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/*** 不知道Proxy.newProxyInstance()方法的参数,自己点进去看一下源码,源码是这样的* public static Object newProxyInstance(ClassLoader loader,* //这是一个接口的.class数组Class<?>[] interfaces,//引用处理InvocationHandler h)throws IllegalArgumentException{Objects.requireNonNull(h);final Class<?>[] intfs = interfaces.clone();final SecurityManager sm = System.getSecurityManager();if (sm != null) {checkProxyAccess(Reflection.getCallerClass(), loader, intfs);}*/public class JDKProxyDemo {public static void main(String[] args) {JDKProxy jdkProxy = new JDKProxy(new Phone());Service o = (Service) Proxy.newProxyInstance(Service.class.getClassLoader(), new Class[]{Service.class}, jdkProxy);o.msg("1111");o.call();}}//实现的功能接口interface Service{//发送信息void msg(String str);//打电话void call();}//委托类class Phone implements Service{@Overridepublic void msg(String str) {System.out.println("发送信息"+str);}@Overridepublic void call() {System.out.println("打电话!");}}//代理类class JDKProxy implements InvocationHandler {private Object target;public JDKProxy(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("操作前,先去洗澡!");Object invoke = method.invoke(target, args);System.out.println("操作后,执行业务");return invoke;}}```
至于为什么需要调用 newProxyInstance,看一下源码注释,源码中是这样描述的 :Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler.
意思是返回指定接口的代理类实例,该接口将方法调用调度到指定的调用处理程序。

文章转载自跬步求索,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




