设计模式--5.4 代理模式-动态代理

1.动态代理

(1)动态代理,是实现阶段不关心代理谁,而在运行阶段才指定代理哪一个对象。相对的说,上面两种 普通代理和强制代理,都是通过写代理类来获取代理,这种是静态代理。

(2)区别:静态代理,需要写代理类,在代理之前要知道我代理的是哪个类;

(3)类图

2.代码

接口类

package com.design.代理模式.动态代理;

public interface IGamePlayer {
    void login(String username , String pwd);

    void killBoss(String name);

    void upgrade();
}    

真实角色

package com.design.代理模式.动态代理;

public class GamePlayer implements IGamePlayer {
    private String name;

    public GamePlayer() {
        super();
    }

    public GamePlayer(String _name) {
        super();
        this.name = _name;
    }

    // 登录
    @Override
    public void login(String username, String pwd) {
        System.out.println("GamePlayer:"+ name +" login.....");

    }

    // 杀怪
    @Override
    public void killBoss(String name) {
        System.out.println("GamePlayer:"+ name +" killBoss.....");

    }

    // 升级
    @Override
    public void upgrade() {
        System.out.println("GamePlayer: "+ name +" upgrade.....");

    }

}

继承 InvocationHandler 类的代理类

package com.design.代理模式.动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class GamePlayIH implements InvocationHandler {

    // 被代理者
    Class<?> cls = null;

    // 被代理者的实例
    Object obj = null;

    // 我要代理谁 _obj
    public GamePlayIH(Object _obj) {
        super();
        this.obj = _obj;
    }

    // 调用被代理者的方法
    // invoke方法,完成对真实方法的调用
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {

        // 参数
        if(args != null){
            for(int i = 0 ; i < args.length ; i++){
                System.out.println("参数" + args[i]);
            }
        }

        // 前置通后
        System.out.println("前置通知。。。");

        // 执行方法,及结果
        Object result = method.invoke(this.obj, args);

        // 后置通知
        if(method.getName().equalsIgnoreCase("login")){
            System.out.println("有人盗我的号!!");
        }

        // 后置通知
        System.out.println("后置通知。。。");

        return result;
    }

}

场景类

package com.design.代理模式.动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Client {
    public static void main(String[] args) {
        // 定义一个游对玩家
        IGamePlayer gp = new GamePlayer("lvyf");

        // 定义一个handler
        InvocationHandler handler = new GamePlayIH(gp);

        // 获得类的classLoader,代理对象由哪一个类加载器加载
        ClassLoader cl = gp.getClass().getClassLoader();

        // 代理对象的类型,即其中有哪些方法
        Class<?>[] interfaces = gp.getClass().getInterfaces();

        // 动态产生一个代理者
        IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl, interfaces, handler);

        // 登录
        proxy.login("lvyf", "123");
        proxy.killBoss("lvyf");
        proxy.upgrade();

        /*
         * 说明
         * 1. IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl, interfaces, handler);
         * 需要使用代理,所以这句话是重新生成一个对象
         * 2. gp.getClass().getInterfaces(); 这句话是查找类的所有接口,然后由handler实现所有接口
         * 3. 由handler里面的invoke方法去接管方法的实现
         * 4. 调用过程
         *     Client ------>   Proxy  ---invoke--->  GamePlayIH  ---invoke--->   IGamePlayer
         * 5. 动态代理就是横向切面编程,在不改变已有代码结构的情况下,增强或控制对象的行为
         * 6. 注意,被代理类GamePlayer必须要实现一个接口IGamePlayer(CGLIB不用)
         *
         * 7.(1) 切面,横切关注点被模块化之后的特殊对象。
         * (如,我在调某个加方之前,希望打印日志,把参数打印出来,)你这个需求就叫横切关注点,打印日志被抽离出来模块化,这个模块化对象就叫做日志切面。
         *      (2) 切入点 jointpoint,比如我希望在加法之前打印日志,那么在加法之前,就叫切入点,joinpoint,或者执行后,打印结果,这个执行后,也叫切入点
         *   (3) 通知,切面必须要完成的工作,如日志,权限验证,叫做通知
         *   (4) 织入,比如打印日志这个动作,就叫织入
         *   (5) 切点 pointcut,aop通过切点定位到特定的切入点。切入点类似于数据库记录,切点类似于查询条件
         */
    }
}
时间: 2024-10-12 16:13:40

设计模式--5.4 代理模式-动态代理的相关文章

设计模式之--代理模式(动态代理)

JDK 提供的动态代理的两个相关的类:InvocationHandler 和 Proxy 一:InvocationHandler  InvocationHandler 接口只提供了一个接口方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; 1 Object proxy 被代理的对象 2 Method method 被代理对象的实现方法 3 Object[] args 被代理对象

设计模式之代理模式(动态代理)

跟之前上一篇静态代理的差不多.这个是在执行的时候动态的产生代理对象,开始是不知道具体的代理对象,是传入具体对象,就产生该具体对象的代理对象.而之前的静态代理是预知要传入的具体对象交给哪一个代理对象执行. 代码实现. 首先定义抽象角色,他是代理对象和具体对象的共同接口.可以是接口,也可以是抽象类. //抽象角色 定义的是一种类型 具有某种共同行为的类型 public interface ProxyInterface{ //定义行为,代理对象和具体对象的共同行为 public void run();

设计模式之--静态代理及动态代理模式

原文链接:http://www.studyshare.cn/blog/details/1181/0 一.概念 代理模式:为其他对象提供一种代理类用以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用 另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用,代理模式属于23中设计模式中的结构型设计模式. 代理模式可分为静态代理和动态代理. 代理结构如下图: 例如:客户(客户类)—>代购(代理类)—>海外下单(海外订单类),普通客户无法直接去海外下单,则向代购公司 下单,代

【设计模式】代理模式:静态代理,动态代理,spring aop

代理模式分为静态代理和动态代理.我们拿链家来举例子,我们本人是真实的对象,有真实的业务需求:需要去找房子:链家是中介,是代理类,他来帮我执行找房子的这个操作. 静态代理: 1.实现一个接口 public interface SearchHome { public void search(); } 2.构建实现接口的委托类 public class Master implements SearchHome { @Override public void search() { System.out.

Spring框架_代理模式(静态代理,动态代理,cglib代理)

共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下:                                      用户库jar包,需要手动发布到tomcat. (每次新建项目) 3) 重新发布项目 * 配置文件错误 (web.xml / struts.xml /bean.xml /hibernate.xml / *.hbm.xml) 明确的提示 * 端口占用 * we

常用设计模式之代理(动态代理)

常用设计模式之代理(动态代理) UML Code1 1 interface Subject{void doSth();} 2 class RealSubject implements Subject{ 3 public void doSth(){ 4 System.out.println("RealSubject doSth...."); 5 } 6 } 7 class ProxyHandler implements InvocationHandler 8 { 9 private Ob

java 代理模式(静态代理、动态代理、Cglib代理) 转载

Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法 代理模式最大的特点就是代理类和实际业务类实现同一个接口(或继承同一父类),代理对象持有一个实际对象的引用,外部调用时操作的是代理对象,而在代理对象的内部实现中又会去调

Java进阶篇设计模式之七 ----- 享元模式和代理模式

前言 在上一篇中我们学习了结构型模式的组合模式和过滤器模式.本篇则来学习下结构型模式最后的两个模式, 享元模式和代理模式. 享元模式 简介 享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 用通俗的话来说就是进行共用.生活中也有一些例子,比如之前很火的共享单车,更早之前的图书馆,编程中经常用的String类,数据库连接池等等.当然,享元模式主要的目的是复用,如果该对象没有的话,就会进行创建. 享

设计模式(二)学习----动态代理

动态代理:动态代理是指在实现阶段不需要关心代理谁,而在运行阶段才指定代理哪一个对象.Spring AOP采用的核心思想就是动态代理设计模式.  下面看动态代理的UML类图: 下面思考问题:invocationHandler的invoke方法是由谁来调用的,代理对象是怎么生成的? 动态代理类: package com.lp.ecjtu.DynamicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect