Java设计模式 ---- 代理模式

一,代理模式

    为其他对象提供一种代理以控制对这个对象的访问。代理模式可以分为静态代理和动态代理模式,动态代理也有通过JDK实现的动态代理模式和CGLib实现的动态代理,下面将分别展示。

二,UML图

   

Subject : 定义了RealSubject和Proxy的共同接口,这样可以在应用过程中通过多态实现接口公用;

RealSubject : 定义Proxy所要代理的真是实体;

Proxy : RealSubject实体的代理类,可以通过实体生成代理对象实现对实体的控制访问;

Proxy和RealSubject之间没有绝对的强一致关系,可以不需要共同实现一个接口实现多态;

三,静态代理模式

    静态代理模式更多的体现在接口的调用,不多做分析,只做一个简单的展示

1,实体类

public class StaticTarget {
    public void targetMethod() {
        System.out.println("被代理的方法");
    }
}

2,代理类

public class StaticProxy {
    private StaticTarget staticTarget;

   
    public StaticProxy(StaticTarget staticTarget) {
        this.staticTarget = staticTarget;
    }

    public void proxyMethod() {
        System.out.println("开始代理...");
        staticTarget.targetMethod();
        System.out.println("结束代理...");
    }
}


3,客户端

public class StaticProxyTest {
    public static void main(String[] args) {
        StaticTarget target = new StaticTarget();
        StaticProxy proxy = new StaticProxy(target);
        proxy.proxyMethod();
    }
}

四,动态代理_JDK实现

    JDK实现的动态代理,被代理类也就是实体类必须实现一个接口,这样会与JDK生成的虚拟代理类存在强一致性关系,从而形成多态调用。

1,顶层接口

public interface ProxyInterface {

    public void targetMethod();
}

2,实体类 -- 实现顶层接口

public class JDKProxyTarget implements ProxyInterface{

    @Override
    public void targetMethod() {
        System.out.println("代理方法...");
    }
}

3,代理对象生成

    该类只负责生成代理对象,具体代理对象的方法调用。JDK在生成代理对象时,也会生成一个该代理对象所属的.class文件。所return的接口对象实际数据该代理类的对象,通过多态调用,所调用的方法为该虚拟类内部的方法,这一块内容将在手写JDK动态代理中分析;

public class JDKProxy {

    private ProxyInterface proxyInterface;

    public JDKProxy(ProxyInterface proxyInterface) {
        this.proxyInterface = proxyInterface;
    }

    public Object instanceProxy() {
        System.out.println("代理方法开始...");
        ProxyInterface instance = (ProxyInterface) Proxy.newProxyInstance(
                proxyInterface.getClass().getClassLoader(),
                proxyInterface.getClass().getInterfaces(),
                new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                method.invoke(proxyInterface, args);
                System.out.println("代理方法结束...");
                return null;
            }
        });
        return instance;
    }

}

    * 该代理对象生成类会先获取实体类的引用,通过该实体类来生成对应的代理类和代理对象;

    * 在newInstance()(自定义方法)方法中,通过调用JDK所提供的Proxy对象来获取代理对象;

   * 在JDK提供的newProxyInstance()中,需要依次传入实体对象的类加载器,类实现的所有接口和InvocationHandler的实现类对象,这里通过匿名内部类获取;

    * InvocationHandler的实现类会重写该接口的invoke()方法,也是整个动态代理最终执行方法的位置,method就是客户端所执行的方法,通过反射方式执行;

4,客户端

public class JDKProxyTest {
    public static void main(String[] args) {
        JDKProxy proxy = new JDKProxy(new JDKProxyTarget());
        ProxyInterface proxyInterface = (ProxyInterface) proxy.instanceProxy();
        System.out.println(proxyInterface.getClass());
        proxyInterface.targetMethod();
    }
}

5,执行接口


    从控制台结果中可以看出,所生成的proxyInterface对象,并不属性原来的实体类,而是JDK自动生成的$Proxy0类。

五,动态代理_CGLib方式

    与JDK代理模式在结构上不同的是 :

    * 实体类不需要继承或者实现任何类和接口,不存在强一致性关系

    * 代理类必须实现MethodInterceptor接口并实现interceptor()方法,

1,实体类

public class CglibTarget {

    public void targetMethod() {
        System.out.println("代理方法...");
    }
}

2,代理类

public class CglibProxy implements MethodInterceptor{

    public Object instanceProcy(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("代理前...");
        Object result = methodProxy.invokeSuper(o, objects);
        System.out.println("代理后...");
        return result;
    }
}

    * 该代理类,在instanceProcy()方法中,通过Enhancer创建出目标类的代理对象;

    * 在实现的intercept()方法中,通过反射进行完成调用;

3,客户端

public class CglibProxyTest {
    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        CglibTarget proxy = (CglibTarget)cglibProxy.instanceProcy(CglibTarget.class);
        proxy.targetMethod();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值