【设计模式】3.代理模式

代理模式

代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。

结构图:

 

Subject:RealSubjectProxy的公共接口

RealSubject:Proxy代理的真实实体

Proxy:代理,与RealSubject实现同一接口,代理就可以代替真实实体。

Java中的代理技术:JDKCGLIBJavaassistASM

Spring中常用JDKCGLIB

Mybatis中使用Javaassist

场景:假如软件的研发过程中,程序员不能直接与客户对接,必须由产品经理与客户进行对接,从而研发部门根据客户的需求进行相应研发工作。这里产品经理和程序员都是研发部门的员工,具有相同的职责(产品研发)。产品经理就代理了程序员的具体工作,可以采用代理模式。

 例:

1. 静态代理方式:

public interface Staff {      // Subject

    void createWebAPP();      // 开发Web应用

    void createAndroidApp();  // 开发Android应用

}
public class Programmer implements Staff {  // RealSubject

    @Override

    public void createWebAPP() {

        System.out.println("Web应用开发");

    }

    @Override

    public void createAndroidApp() {

        System.out.println("Android应用开发");

    }

}
public class Manager implements Staff {       // Proxy

    Programmer programmer;

    @Override

    public void createWebAPP() {

        if (programmer == null) {

            programmer = new Programmer();

        }

        programmer.createWebAPP();

    }

    @Override

    public void createAndroidApp() {

        if (programmer == null) {

            programmer = new Programmer();

        }

        programmer.createAndroidApp();

    }

}
public class Test {

    public static void main(String[] args) {

        Manager manager = new Manager();  

        manager.createAndroidApp();  // 代理执行被代理的方法

        manager.createWebAPP();

    }

}

输出:

Web应用开发
Android应用开发

2. 动态代理方式:

1JDK动态代理

public interface Staff {      // Subject

    void createWebAPP();      // 开发Web应用

    void createAndroidApp();  // 开发Android应用

}
public class Programmer implements Staff {  // RealSubject

    @Override

    public void createWebAPP() {

        System.out.println("Web应用开发");

    }

    @Override

    public void createAndroidApp() {

        System.out.println("Android应用开发");

    }

}
public class DynamicProxyHandler implements InvocationHandler { // Proxy,代理类必须实现InvocationHandler接口

    Object  target;    // 被代理的对象,可以是任何对象(Object是任何类的父类)

    /**

     * 1. 建立代理对象与被代理对象之间的关系

     * @param target 被代理对象

     * @return 被代理对象

     */

    public Object bind(Object target) {

        this.target = target;

        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);

        // 三个参数:target的类加载器;把生成的动态代理的对象挂在哪些接口下,这里是挂在target实现的接口下;实现方法逻辑的代理类

    }

    /**

     *  2. 实现代理逻辑的方法

     *   @param proxy 代理对象(bind方法生成的)

     *   @param method 当前调度的方法

     *   @param args 当前方法参数

     *   @return 代理结果返回

     *   @throws Throwable 异常

     */

    @Override

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

        Object result = method.invoke(target, args);

        return result;

    }

}
public class Test {

    public static void main(String[] args) {

        DynamicProxyHandler proxyHandler = new DynamicProxyHandler();
        // 绑定具体的代理对象,返回给其接口的引用
        Staff proxy = (Staff) proxyHandler.bind(new Programmer()); 

      proxy.createWebAPP(); // 代理执行被代理的方法  proxy.createAndroidApp(); } 
  }

}

输出:

Web应用开发
Android应用开发

(2)CGLIB动态代理

  不需要提供接口,只要一个非抽象类(被代理对象)

依赖:

<dependency>

     <groupId>cglib</groupId>

     <artifactId>cglib</artifactId>

     <version>3.3.0</version>

</dependency>
public class Programmer {        // RealSubject

    public void createWebAPP() {

        System.out.println("Web应用开发");

    }

    public void createAndroidApp() {

        System.out.println("Android应用开发");
} }
public class CglibProxy implements MethodInterceptor {   // 必须实现MethodInterceptor

    /**

     * 生成CGLIB代理对象

     * @param cls Class 类

     * @return Class 类的CGLIB代理对象

     */

    public Object getProxy(Class cls) {

        // CGLIB 增强对象

        Enhancer enhancer = new Enhancer();

        // 设置增强类型

        enhancer.setSuperclass(cls);

        // 定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法

        enhancer.setCallback(this);

        // 生成并返回对象

        return enhancer.create();

    }

    /**

     * 代理逻辑方法

     * @param o 代理对象

     * @param method 方法

     * @param objects 方法参数

     * @param methodProxy 方法代理

     * @return 代理逻辑返回

     * @throws Throwable 异常

     */

    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        // CGLIB 反射调用的真实对象方法

        Object result = methodProxy.invokeSuper(o,objects);

        return result;

    }

}
public class Test {

    public static void main(String[] args) {

        CglibProxy cp = new CglibProxy();

        Programmer pg = (Programmer)cp.getProxy(Programmer.class);

        pg.createWebAPP();

        pg.createAndroidApp();

    }
}

猜你喜欢

转载自www.cnblogs.com/jiazhongxin/p/12802712.html
今日推荐