Java基础 (15) 代理模式

2019-02-20  本文已影响0人  perry_Fan

问题1. 静态代理的使用方式和场景
问题2. 动态代理如何实现和场景

一. 静态代理

静态代理的实现模式一般是:首先创建一个接口,然后创建具体实现类来实现这个接口,然后再创建一个代理类同样实现这个接口。
举例:

1)抽象主题(接口)
public interface Movie {
    void play();
}
2)被代理角色(目标类)与代理角色(代理类)
public class RealMovie implements Movie {
    @Override
    public void play() {
        // TODO Auto-generated method stub
        System.out.println("您正在观看电影 《肖申克的救赎》");
    }
}
public class Cinema implements Movie {

    RealMovie movie;
    public Cinema(RealMovie movie) {
        super();
        this.movie = movie;
    }

    @Override
    public void play() {
        guanggao(true);    // 代理类的增强处理
        movie.play();     // 代理类把具体业务委托给目标类,并没有直接实现
        guanggao(false);    // 代理类的增强处理
    }

    public void guanggao(boolean isStart){
        if ( isStart ) {
            System.out.println("电影马上开始了,爆米花、可乐、口香糖9.8折,快来买啊!");
        } else {
            System.out.println("电影马上结束了,爆米花、可乐、口香糖9.8折,买回家吃吧!");
        }
    }
}
3)客户端
package com.frank.test;
public class ProxyTest {
    public static void main(String[] args) {
        RealMovie realmovie = new RealMovie();
        Movie movie = new Cinema(realmovie);
        movie.play();
    }
}

二. 动态代理

1)抽象主题(接口)
public interface Subject {
    public void doSomething();
}
2)被代理角色(目标类)
public class RealSubject implements Subject {
    public void doSomething() {
        System.out.println("call doSomething()");
    }
}
3)代理角色(代理类)与客户端

在动态代理中,代理类及其实例是程序自动生成的,因此我们不需要手动去创建代理类。在Java的动态代理机制中,InvocationHandler(Interface)接口和Proxy(Class)类是实现我们动态代理所必须用到的。事实上,Proxy通过使用InvocationHandler对象生成具体的代理代理对象,下面我们看一下对InvocationHandler接口的实现:

public class ProxyHandler implements InvocationHandler {

    private Object proxied;   // 被代理对象

    public ProxyHandler(Object proxied) {
        this.proxied = proxied;
    }

    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {

        // 在转调具体目标对象之前,可以执行一些功能处理
        System.out.println("前置增强处理: yoyoyo...");

        // 转调具体目标对象的方法(三要素:实例对象 + 实例方法 + 实例方法的参数)
        Object obj = method.invoke(proxied, args);

        // 在转调具体目标对象之后,可以执行一些功能处理
        System.out.println("后置增强处理:hahaha...");

        return obj;
    }
}

在实现了InvocationHandler接口后,我们就可以创建代理对象了。在Java的动态代理机制中,我们使用Proxy类的静态方法newProxyInstance创建代理对象,如下:

public class Test {
    public static void main(String args[]) {

        // 真实对象real
        Subject real = new RealSubject();

        // 生成real的代理对象
        Subject proxySubject = (Subject) Proxy.newProxyInstance(
                Subject.class.getClassLoader(), new Class[] { Subject.class },
                new ProxyHandler(real));

        proxySubject.doSomething();
        System.out.println("代理对象的类型 : " + proxySubject.getClass().getName());
        System.out.println("代理对象所在类的父类型 : " + proxySubject.getClass().getGenericSuperclass());
    }
}/** Output
        前置增强处理: yoyoyo...
        call doSomething()
        后置增强处理:hahaha...
        代理对象的类型 : com.sun.proxy.$Proxy0
        代理对象所在类的父类型 : class java.lang.reflect.Proxy
 **/

静态:由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。
动态:在程序运行时运用反射机制动态创建而成。

上一篇 下一篇

猜你喜欢

热点阅读