23种设计模式之一代理模式的探讨

1、代理模式:

代理意为“代为处理”,有些事情交给代理人去处理,而目标对象只聚焦核心的业务,这就更加符合面向对象,各司其职,专业的事情交给专业的人来做。生活中用到代理随处可见。比如明星要演出,一些事情如商谈合作,出场费用,演出项目,酒店安排,出现方式等都要经济人去协调洽谈。这个时候经济人其实就是明星的代理人。在java中把这种场景的应用抽象成一种代理模式。

2、实现原理:

就是原本直接找具体的对象就可以的事情,现在要先经过该对象的代理对象来处理。比如请明星商演,要先联系他的代理确定档期,出场费,衣食住行及规格等等。然后明星才去演出。换到程序中,就是对象执行具体的方法前后先做一下其他的程序处理。代理模式的用途其实就是对目标对象的增强。对目标对象的一些功能添加额外的功能。

3、实现方式

实现方式有三种:静态代理、jdk动态代理(一般称动态代理)、cglib动态代理(一般称为cglib代理)

3.1、静态代理:

程序设计的时候就已经又代理类了。

// 表演接口
public interface Perform {
    void sing();
    void dance();
}

// 明星类实现了表演接口
public class SuperStar implements Perform {
    @Override
    public void sing() {
        System.out.println("明星开始唱歌 ... ");
    }
    @Override
    public void dance() {
        System.out.println("明星开始跳舞 ... ");
    }
}
// 代理类也实现了表演接口
public class StaticProxy implements Perform {
    // 内部并维护了表演接口的引用
    private Perform star;
    public StaticProxy(Perform star) {
        this.star = star;
    }
    
    @Override
    public void sing() {
        System.out.println("已审查");
        System.out.println("已收出场费");
        star.sing();
        System.out.println("接明星回下榻五星级酒店休息");
    }

    @Override
    public void dance() {
        System.out.println("已审查");
        System.out.println("已收出场费");
        star.dance();
        System.out.println("接明星回下榻五星级酒店休息");
    }
    
    // 静态代理测试 
    public static void main(String[] args) {
        StaticProxy staticProxy = new StaticProxy(new SuperStar());
        staticProxy.sing();
        staticProxy.dance();
    }
}
3.2、jdk动态代理:

程序运行的时候才动态创建代理,采用jdk自带的proxy实现

public class TestDynamicProxy {
    public static void main(String[] args) {
        // 创建目标对象
        SuperStar target = new SuperStar();

        // 根据目标对象创建代理对象
        Perform dynamicProxy = (Perform) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("表演前收出场费");
                Object result = method.invoke(target, args);
                System.out.println("表演完回酒店喝酒");
                return result;
            }
        });

        // 调用代理对象的方法
        dynamicProxy.sing();
    }
}
3.3、cglib动态代理:

程序运行的时候才动态创建代理,采用第三方cglib实现。

// 引入三方jar cglib
<dependency>
     <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>2.2.2</version>
</dependency>

// 去除实现接口
public class SuperStar2{
    public void sing() {
        System.out.println("明星开始唱歌 ... ");
    }
    public void dance() {
        System.out.println("明星开始跳舞 ... ");
    }
}

public class TestCglibProxy {
    public static void main(String[] args) {
        // 1、创建增强对象Enhancer
        Enhancer enhancer = new Enhancer();
        // 2、设置要代理的目标类未代理类的父类
        enhancer.setSuperclass(SuperStar2.class);
        // 3、设置回调函数
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] agrs, MethodProxy methodProxy) throws Throwable {
                System.out.println("收出场费");
                return methodProxy.invokeSuper(o, agrs);
            }
        });
        // 4、创建代理对象
        SuperStar2 cglibProxy = (SuperStar2) enhancer.create();
        // 5、执行代理对象方法
        cglibProxy.sing();

    }

总结和对比:

1、静态代理:要求代理类和目标类都要实现同一接口,并且代理类内部维护了目标类对象的引用。
2、jdk动态代理:只要求目标对象要实现接口,代理类不需要实现接口。
3、cglib动态代理:要引入cglib包,不需要目标类实现接口即可代理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值