博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java设计模式--代理模式+动态代理+CGLib代理
阅读量:6920 次
发布时间:2019-06-27

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

静态代理

抽象主题角色:声明真实主题和代理主题的共同接口。

代理主题角色:代理主题内部含有对真实主题的引用,从而在任何时候操作真实主题对象;代理主题提供一个与真实主题相同的接口,以便在任何时候都可以代替真实主题。代理角色通常在将客户端调用传递给真实的主题之前或之后,都要执行某个操作,而不是单纯的传递调用。

真实主题角色:定义代理角色所代表的的真实对象。

UML图:

抽象主题

public interface Subject {    void request();}

 

真实主题

public class RealSubject implements Subject {    @Override    public void request() {        System.out.println("真实对象的方法");    }}

 

代理主题

public class ProxySubject implements Subject {    private RealSubject subject;    public ProxySubject() {    }    @Override    public void request() {        pre();        if (subject == null){            subject = new RealSubject();        }        subject.request();        post();    }    private void pre(){        System.out.println("方法执行之前");    }    private void post(){        System.out.println("方法执行之后");    }}

 

执行:

public static void main(String[] args) throws Exception {        ProxySubject subject = new ProxySubject();        subject.request();    }

 

输出:

方法执行之前真实对象的方法方法执行之后 

动态代理

JDK自带的动态代理,实现InvocationHandler接口。

声明接口

public interface MyConnection extends AutoCloseable {    void createStatement() throws Exception;    @Override    void close() throws Exception;}

 

真实主题

public class MyDefaultConnection implements MyConnection {    @Override    public void createStatement() throws Exception {        System.out.println("Create Statement ...");    }    @Override    public void close() throws Exception {        System.out.println("Close Connection ...");    }}

 

代理主题

public class MyConnectionProxy implements InvocationHandler {    private MyConnection conn;    private MyConnection proxyConn;    public MyConnectionProxy(MyConnection conn) {        this.conn = conn;        this.proxyConn = (MyConnection) Proxy.newProxyInstance(MyConnection.class.getClassLoader(), new Class
[] {MyConnection.class}, this); } public MyConnection getConn() { return conn; } public MyConnection getProxyConn() { return proxyConn; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); System.out.println("==代理方法:" + methodName); if("close".equals(methodName)){ System.out.println("**不执行close方法"); }else{ return method.invoke(conn, args); } return null; }}

 

执行:

public static void main(String[] args) throws Exception {        MyConnection connection = new MyDefaultConnection();        MyConnectionProxy proxy = new MyConnectionProxy(connection);        proxy.getProxyConn().createStatement();        proxy.getProxyConn().close();    }

 

你会发现我的代理对象去哪里了?实际上我放在InvocationHandler的实现类里面了,这里参考的是mybatis源码的设计。

输出:

==代理方法:createStatementCreate Statement ...==代理方法:close**不执行close方法

CGLib

面试的时候可能问你:JDK动态代理和CGLib的区别是什么,说的最多的就是JDK需要一个接口,而CHLib不需要接口就能实现动态代理。

cglib
cglib
3.2.12

 

需要代理的对象

public class Programmer {    public void work(){        System.out.println("程序员正在敲代码...");    }    public final void finalCannotOverride(){        System.out.println("final方法不能被生成的子类覆盖");    }    private void privateCannotOverride(){        System.out.println("private方法不能被生成的子类覆盖");    }}

 

代理类

public class ProgrammerProxy implements MethodInterceptor {    // 真实对象    private Object realObject;    // 代理对象    private Object proxyObject;    public ProgrammerProxy(Object realObject) {        this.realObject = realObject;        Enhancer enhancer = new Enhancer();        // 设置需要代理的对象        enhancer.setSuperclass(realObject.getClass());        // 设置代理人        enhancer.setCallback(this);        this.proxyObject = enhancer.create();    }    public Programmer getProxyObject() {        return (Programmer) proxyObject;    }    @Override    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {        pre();        Object result = method.invoke(realObject, objects);        post();        return result;    }    private void pre(){        System.out.println("==先吃早餐");    }    private void post(){        System.out.println("==下班打卡");    }}

 

执行:

public static void main(String[] args) throws Exception {        Programmer programmer = new Programmer();        ProgrammerProxy proxy = new ProgrammerProxy(programmer);        proxy.getProxyObject().finalCannotOverride();        proxy.getProxyObject().work();    }

 

输出:

final方法不能被生成的子类覆盖==先吃早餐程序员正在敲代码...==下班打卡

 

转载于:https://www.cnblogs.com/LUA123/p/10882784.html

你可能感兴趣的文章
解决win7/win8 winsxs目录不断变大的问题
查看>>
windows 20008DHCP中继
查看>>
docker 容器网络篇
查看>>
DAY 19
查看>>
AD在windows2003中的更新
查看>>
Windows PowerShell 配置文件
查看>>
javap命令详解
查看>>
ELK之logstash长久运行
查看>>
vSphere Web Client连接vCenter提示flash崩溃
查看>>
kft-activiti-demo
查看>>
变更管理7R
查看>>
2016年上半年网络工程师培训考试感想
查看>>
LESS CSS 框架简介
查看>>
Kobject浅析
查看>>
Shell常用命令小结
查看>>
我的友情链接
查看>>
jboss
查看>>
repmgr实现pg流复制失效自动切换
查看>>
Ubuntu使用ufw进行防火墙设置
查看>>
Innodb 关于blob、text字段的存储以及性能
查看>>