博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
代理模式
阅读量:5057 次
发布时间:2019-06-12

本文共 3451 字,大约阅读时间需要 11 分钟。

代理模式,为其他对象提供一种代理以控制对这个对象的访问。【大话设计模式】

一张图,说明代理模式的结构。代理在客户端和目标对象起到的是中介的作用,一种桥梁,也如大话设计模式中所言,为他人做嫁衣。

代理模式按照创建时期可以分为两类:静态代理、动态代理。

静态代理

首先介绍一下静态代理,静态代理的结构完全契合于上图,需要首先定义个接口,业务实现接口,然后定义代理类,且需要实现所有的相同的接口。

首先,定义一个业务接口:

public interface Account{    public void save();}

然后,定义代理类,实现业务接口

public class AccountImpl implements Account{        @Override    public void save()    {        System.out.println("保存中。。。。。");    }    }

接下来,实现代理类

public class AccountProxy implements Account{    private AccountImpl accountImpl;        public AccountProxy(AccountImpl accountImpl)    {        this.accountImpl = accountImpl;    }        @Override    public void save()    {        System.out.println("开始保存啦。。。。。");        accountImpl.save();        System.out.println("保存结束啦。。。。。");    }    }

客户端类:

public class TestAccount{    public static void main(String[] args)    {        AccountImpl accountImpl = new AccountImpl();        AccountProxy proxy = new AccountProxy(accountImpl);        proxy.save();    }}

 结果如下:

开始保存啦。。。。。保存中。。。。。保存结束啦。。。。。

这样静态的代理模式就可以完成了。但是,有个问题,就是代理类要实现所有的业务接口,这样就会造成很多代码重复,为了解决这些,需要用接下来的动态代理模式来实现。

动态代理模式

我们接着用上边的例子,通过动态代理模式实现代理。

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class DynamicProxy implements InvocationHandler{    private Object target;        public Object newInstance(Object target)    {        this.target = target;        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable    {        Object result = null;        System.out.println("begin");        result = method.invoke(target, args);        System.out.println("end");        return result;    }}

客户端调用如下:

import com.huawei.model.proxy.Account;import com.huawei.model.proxy.AccountImpl;public class TestProxy {            public static void main(String[] args) {            DynamicProxy proxy = new DynamicProxy();            //在这里进行真正的对象传入          Account account= (Account )proxy.newInstance(new AccountImpl());            account.save();      } }

通过对比,我们可以发现,通过动态代理,我们省略了关于代理接口的实现方法,不用讲所有需要被代理的全部方法都要实现,即可实现代理功能。

 

通过以上方法实现,我们仍然是需要接口的,如果没有接口,该怎么办?

CGLib动态代理

CGLib是一个类库,它可以在运行期间动态生成字节码,动态生成代理类。

代码如下:

import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class CglibProxy implements MethodInterceptor{    public 
T getProxy(Class
cls) { return (T)Enhancer.create(cls, this); } @Override public Object intercept(Object obj, Method method, Object[] arg2, MethodProxy proxy) throws Throwable { System.out.println("开始保存啦。。。。。"); Object result = proxy.invokeSuper(obj, arg2); System.out.println("保存结束啦。。。。。"); return result; } }

客户端调用代码:

import com.huawei.model.proxy.Account;import com.huawei.model.proxy.AccountImpl;public class TestProxy{    public static void main(String[] args)    {        CglibProxy proxy = new CglibProxy();        Account account = proxy.getProxy(AccountImpl.class);        account.save();    }}

输出结果:

开始保存啦。。。。。保存中。。。。。保存结束啦。。。。。

虽然该方法比上述两种方式均更加灵活,但是其也有自己的缺点,就是会拦截被代理类的所有方法。

参考链接:

https://www.zhihu.com/question/20794107

http://blog.csdn.net/wangyongxia921/article/details/46240877

转载于:https://www.cnblogs.com/woniu4/p/8360761.html

你可能感兴趣的文章
linux swoole
查看>>
An Easy Problem?! - POJ 2826(求面积)
查看>>
【题解】[P4178 Tree]
查看>>
Jquery ui widget开发
查看>>
css3实现循环执行动画,且动画每次都有延迟
查看>>
更改git仓库地址
查看>>
有标号DAG计数 [容斥原理 子集反演 组合数学 fft]
查看>>
Recipe 1.4. Reversing a String by Words or Characters
查看>>
Rule 1: Make Fewer HTTP Requests(Chapter 1 of High performance Web Sites)
查看>>
sql注入
查看>>
「破解」Xposed强
查看>>
Linux 平台下 MySQL 5.5 安装 说明 与 示例
查看>>
src与href的区别
查看>>
ABAP工作区,内表,标题行的定义和区别
查看>>
《xxx重大需求征集系统的》可用性和可修改性战术分析
查看>>
Python 中 创建类方法为什么要加self
查看>>
关于indexOf的使用
查看>>
【转】JS生成 UUID的四种方法
查看>>
英语单词
查看>>
centos6.8下安装matlab2009(图片转帖)
查看>>