暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

代理模式

跬步求索 2021-11-05
167

在很多框架中,代理模式使用的比较多,在学习mybatis源码过程中大量用到代理模式。今天复习一下几种代理模式:**静态代理**和**动态代理**

代理模式就相当于一个中介,比如房产中介,婚庆公司,它本身并没有实现房产,但是他代理了房产。

优点:

1.具有高扩展性(因为中间插入了中间层,可以对原有功能进行扩展)

2.职责清晰。

缺点:由于增加了中间层,可能导致处理效率变慢


***第一种情况:静态代理***



```java
package 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或者源码理清楚。

测试案例


```java
package 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{
@Override
public void msg(String str) {
System.out.println("发送信息"+str);
}




@Override
public void call() {
System.out.println("打电话!");
}
}
//代理类
class JDKProxy implements InvocationHandler {
private Object target;




public JDKProxy(Object target) {
this.target = target;
}




@Override
public 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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论