设计模式(八)代理模式(Proxy)-结构型

Proxy 代理模式:解耦

日常开发中的日志权限事务处理等。

实现原理:

  • 一个抽象目标类即一个接口,有相关方法名;
  • 一个具体目标类,实现该接口和相关的方法;
  • 一个代理类,调用目标具体类并加上自己需要的逻辑;
  • 客户端实例化代理类,调用代理类的方法

代理模式实现原理图


代理模式

代理模式:是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

按照代理的创建时期,代理类可以分为两种。

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

动态代理:在程序运行时,运用反射机制动态创建而成。

静态代理模式如下:

1.抽象目标类

public interface Subject(){
    public void Request();
}

2.具体目标类

public class RealSubject implements Subject(){
    public void Request(){
    };
}

3.代理类

public class Proxy (){

    private RealSubject realSubject;
    public void Request(){
        /**附加逻辑**/
        realSubject.Request();
        /**附加逻辑**/
    };
}

动态代理: JDK动态代理

JDK动态的代理的3个主要类:

Proxy:代理类

InvocationHandler: 接口

Method:要被调用的方法

TaxInterface.java

public interface TaxInterface {
    public void doTax();
}

Tax.java

public class Tax implements TaxInterface{

    @Override
    public void doTax() {
        System.out.println("进行所得税计算的逻辑处理");
    }
}

TimeProxy.java

public class TimeProxy implements InvocationHandler{
    private Object obj;
    //绑定代理对象
    public Object bind(Object obj){
        this.obj = obj;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }

    //实现代理
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object result = null;
        try {
            long startTime = System.nanoTime();
            result = method.invoke(obj, args);
            long endTime = System.nanoTime();
            System.out.println("计算程序运行时间 :" +(endTime-startTime));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

客户端测试:Client.java

public class Client {
    public static void main(String[] args) {
        TimeProxy timeProxy = new TimeProxy();
        TaxInterface taxInterface = (TaxInterface)timeProxy.bind(new Tax());
        taxInterface.doTax();
    }
}

JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。

Cglib动态代理

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

示例如下:

BookFacadeCglib.java

package com.ldw.dao;  

public interface BookFacade {
    public void addBook();
}  

BookCadeImpl1.java

package com.ldw.dao.impl;
/**
 * 这个是没有实现接口的实现类
 *
 * @author csu.ldw
 *
 */
public class BookFacadeImpl1 {
    public void addBook() {
        System.out.println("增加图书的普通方法...");
    }
}

BookFacadeProxy.java

package com.ldw.proxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
 * 使用cglib动态代理
 *
 * @author student
 *
 */
public class BookFacadeCglib implements MethodInterceptor {
    private Object target;
    /**
     * 创建代理对象
     *
     * @param target
     * @return
     */
    public Object getInstance(Object target) {
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        // 回调方法
        enhancer.setCallback(this);
        // 创建代理对象
        return enhancer.create();
    }  

    @Override
    // 回调方法
    public Object intercept(Object obj, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        System.out.println("事物开始");
        proxy.invokeSuper(obj, args);
        System.out.println("事物结束");
        return null;
    }
} 

TestCglib.java

package com.ldw.test;  

import net.battier.dao.impl.BookFacadeImpl1;
import net.battier.proxy.BookFacadeCglib;  

public class TestCglib {  

    public static void main(String[] args) {
        BookFacadeCglib cglib=new BookFacadeCglib();
        BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());
        bookCglib.addBook();
    }
}  

应用

SpringAOP、Struts拦截器、日志管理等。

附加

struts2的拦截器属于AOP思想,采用了代理模式

struts2中,最重要的一个类是org.apache.struts2.dispatcher.FilterDispatcher用户通过浏览器提交一个HttpServletRequest请求后,请求被在web.xml中的过滤器FilterDispatcher拦截在FilterDispatcher过滤器中首先询问ActionMapper是否需要调用某个Action来处理请求,如果ActionMapper决定需要调用某个请求,FilterDispatcher则把请求的处理交给ActionProxy,ActionProxy通过配置文件struts.xml找到需要调用的Action类,然后ActionProxy创建一个ActionInvocation实例并通用该Action但在调用之前,ActionInvocation会根据配置加载Action相关的Intercepter,等Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的Result结果。

时间: 2024-11-08 01:58:44

设计模式(八)代理模式(Proxy)-结构型的相关文章

设计模式12: Proxy 代理模式(结构型模式)

Proxy 代理模式(结构型模式) 直接与间接 人们对于复杂的软件系统常常有一种处理手法,即增加一层间接层,从而对系统获得一种更为灵活.满足特定需求的解决方案.如下图,开始时,A需要和B进行3次通信,当增加一个C后,C和B只需要通信一次,A和C通信3次就好了. 动机(Motivation) 在面向对象系统中某些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全机制,或者需要进程外的访问等),直接访问会给使用者.或者系统结构带来很多麻烦. 如果在不失去透明操作对象的同时来管理.控制这些

设计模式之代理模式(Proxy)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

设计模式 笔记 代理模式 Proxy

//---------------------------15/04/21---------------------------- //Proxy 代理模式-----对象结构型模式 /* 1:意图: 为其他对象提供一种代理以控制对这个对象的访问. 2:别名: Surrogate 3:动机: 4:适用性: 1>远程代理: 为一个对象在不同的地址空间提供局部代表. 2>虚代理: 根据需要创建开销很大的对象. 3>保护代理: 控制对原始对象的访问.保护代理用于对象应该有不同的访问权限的时候.

设计模式三: 代理模式(Proxy) -- JDK的实现方式

设计模式三: 代理模式(Proxy) -- JDK的实现方式 简介 代理模式属于行为型模式的一种, 控制对其他对象的访问, 起到中介作用. 代理模式核心角色: 真实角色,代理角色; 按实现方式不同分为静态代理和动态代理两种; 意图 控制对其它对象的访问. 类图 实现 JDK自带了Proxy的实现, 下面我们先使用JDK的API来演示代理如何使用, 随后再探究Proxy的实现原理,并自己来实现Proxy. JDK代理类的使用: (InvocationHandler,Proxy) 使用JDK实现的代

23种设计模式-----创建型模式、结构型模式

一.创建型模式(都是用来帮助创建对象的) 1.单例模式 作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点 应用:Windows的任务管理器.回收站:项目中读取配置文件的类:网站的计数器:应用程序的日志应用:数据库连接池:操作系统的文件系统:Application:Spring中的bean:Servlet:spring MVC框架/struts1框架中的控制器对象 选用:占用资源小.不需要延时加载--------枚举-->饿汉           占用资源大 .需要延时    --

Android设计模式之代理模式 Proxy

一.概述 代理模式也是平时比较常用的设计模式之一,代理模式其实就是提供了一个新的对象,实现了对真实对象的操作,或成为真实对象的替身.在日常生活中也是很常见的.例如A要租房,为了省麻烦A会去找中介,中介会替代A去筛选房子,A坐享中介筛选的结果,并且交房租也是交给中介,这就是一个典型的日常生活中代理模式的应用.平时打开网页,最先开到的一般都是文字,而图片等一些大的资源都会延迟加载,这里也是使用了代理模式. 代理模式的组成: Abstract Subject:抽象主题-声明真实主题和代理主题共同的接口

设计模式之代理模式---Proxy Pattern

模式的定义 代理模式(Proxy Pattern)也叫做委托模式,定义如下: Provide a surrogate or placeholder for another object to control access to is. 为其他对象提供一种代理以控制对这个对象的访问. 类型 结构类 模式的使用场景 想想现实世界中,打官司为什么要找个律师?因为你不想参与中间过程的是是非非,只要完成自己的工作就可以,其它的事情比如事前调查,事后追查都可以由律师来负责,这就可以减少你的负担.代理模式使用

设计模式-11 外观模式(结构型模式)

一  外观模式 外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性. 主要解决:降低访问复杂系统的内部子系统时的复杂度,简化客户端与之的接口. 关键代码:在客户端和复杂系统之间再加一层,这一次将调用顺序.依赖关系等处理好. 使用场景: JAVA 的三层开发模式 1.为复杂的模块或子系统提供外界访问的模块. 2.子系统相对独立. 3.预防低水平人员带来的风险. 类图

大熊君说说JS与设计模式之------代理模式Proxy

一,总体概要 1,笔者浅谈 当我们浏览网页时,网页中的图片有时不会立即展示出来,这就是通过虚拟代理来替代了真实的图片,而代理存储了真实图片的路径和尺寸,这就是代理方式的一种. 代理模式是比较有用途的一种模式,而且变种较多(虚代理.远程代理.copy-on-write代理.保护代理.Cache代理.防火墙代理.同步代理.智能指引),应用场合覆盖从小结构到整个系统的大结构, 我们也许有代理服务器等概念,代理概念可以解释为:在出发点到目的地之间有一道中间层,意为代理. 代理对象角色内部含有对真实对象的