美文网首页Java 杂谈JavaSpring-Boot
java设计模式-代理模式(proxy pattern)

java设计模式-代理模式(proxy pattern)

作者: bugWriter_y | 来源:发表于2019-07-13 20:59 被阅读7次
1.jpg

简述

提到代理模式,脑海中第一个想到的就是springAop。日常工作中,我们用springAop来实现统一权限管理统一日志管理统一数据库事务处理等等任务。

上面提到的任务就是代理模式的作用。它能在不改变原有功能的基础上增加新的特性。所以说代理模式符合面向对象设计的开闭原则

开闭原则:对扩展开放,对修改关闭

在我们的日常生活中,明星和经纪人的关系很像代理模式的运作模式。活动主办方通过和经纪人联系,然后让经纪人安排明星的演出活动。这里活动主办方是调用者,明星是真实对象,而经纪人就是代理对象。明星只需要负责活动的演出,其他的一切事情都由经纪人去处理。

这个例子也体现了代理模式的另一个作用。就明星而言,经纪人能让其更加专注于演出,而不用去考虑其他与演出关系不大的事情。很多情况下,我们使用代理模式的初衷可能也是如此,抽出公共的不属于业务的部分,让业务开发人员更专注于业务逻辑的处理

分类

下面我们看看代理模式的分类

Snipaste_2019-07-13_20-57-30.png
  • 从代理类是否需要手动编写来分

    • 代码编译运行之前需要手动编写代理类:静态代理
    • 不需要编写,运行时自动创建代理对象:动态代理
  • 动态代理从真实对象是否需要实现接口

    • 实现了接口:jdk和cglib都可以
    • 不需要实现接口:只能时cglib

springAOP默认是当真实对象实现了接口采用jdk动态代理,没有实现接口采用cglib动态代理。

代码实现

最后我们看看代码怎么实现

1. 无代理

//真实对象
public class RealObject{
    public void doSomething(){
        System.out.println("real object do something");
    }
}
//调用者
@Test
public void noProxy(){
    RealObject realObject = new RealObject();
    realObject.doSomething();
}

2. 静态代理

//真实对象(实现了接口)
public class RealObject  implements Iface{
    public void doSomething(){
        System.out.println("real object do something");
    }
}
//接口
public interface Iface {
    void doSomething();
}
//代理类
public class StaticProxy implements Iface{
    private Iface target;
    public StaticProxy(Iface target){
        this.target=target;
    }
    @Override
    public void doSomething() {
        System.out.println("do something before realObject do something");
        target.doSomething();
        System.out.println("do something after realObject do something");
    }
}
//调用者
@Test
public void staticProxy(){
    Iface realObject=new RealObject();
    Iface proxy = new StaticProxy(realObject);
    proxy.doSomething();
}

3. jdk动态代理

//真实对象(实现了接口)
public class RealObject  implements Iface{
    public void doSomething(){
        System.out.println("real object do something");
    }
}
//接口
public interface Iface {
    void doSomething();
}
//这个不是代理类,而是代理处理逻辑(不然哪里让你写新增的功能!!!)
public class JdkProxyHandler implements InvocationHandler {
    private Object target;
    public JdkProxyHandler(Object target){
        this.target=target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("do something before realObject do something");
        Object invoke = method.invoke(target, args);
        System.out.println("do something after realObject do something");
        return invoke;
    }
}
//调用者
@Test
public void jdkProxy(){
    Iface realObject=new RealObject();
    Iface proxy = (Iface) Proxy.newProxyInstance(Iface.class.getClassLoader(), new Class[]{Iface.class}, new JdkProxyHandler(realObject));
    proxy.doSomething();
}

4. cglib动态代理

需要cglib包,spring项目自带cglib包

//真实对象(不用实现接口)
public class RealObject{
    public void doSomething(){
        System.out.println("real object do something");
    }
}
//这个不是代理类,而是代理处理逻辑(不然哪里让你写新增的功能!!!)
public class CglibProxyHandler implements MethodInterceptor {
    private Object target;
    public Object getInstance(Object target){
        this.target=target;
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("do something before realObject do something");
        Object invoke = methodProxy.invokeSuper(object, args);
        System.out.println("do something after realObject do something");
        return invoke;
    }
}
//调用者
@Test
public void cglibProxy() {
    RealObject realObject = new RealObject();
    CglibProxyHandler cglibProxyHandler = new CglibProxyHandler();
    RealObject proxy = (RealObject)cglibProxyHandler.getInstance(realObject);
    proxy.doSomething();
}

相关文章

网友评论

    本文标题:java设计模式-代理模式(proxy pattern)

    本文链接:https://www.haomeiwen.com/subject/unzmkctx.html