设计模式——代理模式

一、介绍

对其他对象提供一种代理以控制对这个对象的访问。

它有如下角色:

Subject:一个抽象的角色,是一个接口。

RealSubject:真实对象,是对接口的实现。

Proxy:代理对象,里面持有被代理对象(RealSubject)的引用,所以操作代理对象时从而可以操作真实对象,并且在操作真实对象之前可以可以加一些其他的操作,比如对真实对象的权限访问等等。

下面是代理模式的UML类图:

二、分类

  1. 静态代理
  2. 动态代理

三、实现

     1、静态代理的实现

public interface Subject {

    void doSomething();
    
}
public class SubjectImpl implements Subject {
    @Override
    public void doSomething() {
        System.out.println("do something ……");
    }
}
public class Proxy implements Subject{

    private final Subject subject = new SubjectImpl();

    @Override
    public void doSomething() {
        System.out.println("before doing");
        subject.doSomething();
        System.out.println("after doing");
    }
}
public class ProxyTest {

    public static void main(String[] args) {
        Proxy proxy = new Proxy();
        proxy.doSomething();
    }
}

这种实现方式在程序执行之前就已经由我们写好的代理类在执行之前就已经知道了要代理的对象的是谁,而不是由程序自动生成的,这就是指的静态。这样的实现方式的缺点就是不容易维护,比如接口发生了改变,添加或者减少了方法,那么就需要真实对象和代理对象都发生改动。

 

     2、动态代理的实现

          动态代理实现有两种方式,一种是jdk实现,另一只就是cglib实现。

          jdk的实现:

               1:创建一个类实现InvocationHandler接口,并且重写invoke方法。

               2:调用Proxy的newProxyInstance创建一个代理类。

               3:用代理类调用需要的方法。

public interface Subject {

    void doSomething();

}
public class SubjectImpl implements Subject {
    @Override
    public void doSomething() {
        System.out.println("do something ……");
    }
}
public class SubjectProxy {

    public static Object proxy(){
        Object object = Proxy.newProxyInstance(SubjectImpl.class.getClassLoader(), 
                SubjectImpl.class.getInterfaces(), new MyInvocationHandler());
        return  object;
    }

    private static class MyInvocationHandler implements InvocationHandler {
        private final Subject subject = new SubjectImpl();

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("before doing");
            Object object = method.invoke(subject, args);
            System.out.println("after doing");
            return object;
        }
    }
}
public class ProxyTest {

    public static void main(String[] args) {
        Subject subject = (Subject) SubjectProxy.proxy();
        subject.doSomething();
    }
}

 

cglib实现:

1:创建一个类实现MethodInterceptor接口并且重写Interpect方法。

2:创建Enhandcer设置父类、回调创建代理类

3:用代理类调用需要的方法。

public class Subject {

    public void doSomething(){
        System.out.println("do something ……");
    }

}
public class SubjectProxy {

    public static Object proxy(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Subject.class);
        enhancer.setCallback(new MyInterceptor());
        return enhancer.create();
    }

    private static class MyInterceptor implements MethodInterceptor{
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("before doing");
            Object object = methodProxy.invokeSuper(o, objects);
            System.out.println("after doing");
            return object;
        }
    }
}
public class ProxyTest {

    public static void main(String[] args) {
        Subject subject = (Subject) SubjectProxy.proxy();
        subject.doSomething();

    }
}

 

jdk实现和cglib实现对比:

jdk实现cglib实现
利用用反射实现利用asm开源包通过字节码重组实现
目标对象必须实现接口目标对象不需要实现接口,但是不能代理final修饰的方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值