zoukankan      html  css  js  c++  java
  • 动态代理

    一.动态代理与继承和装饰者模式相比

    增强手段有三种

    1.继承:

    特点:被增强对象不能变;增强内容不能变

    2.装饰者模式

    特点:被增强对象可变,但增强内容不可变

    3.动态代理

    特点:被增强对象可变,增强内容可变

    二. 用代理工厂创建代理对象并使用

    目标对象:manWaiter类,它实现了Waiter接口

    增强对象:接口BeforeAdvice#before():前置增强对象;

         接口 AfterAdvice#after():后置增强对象

    1. 代理工厂类

    /*
    代理对象工厂类,它用来生成代理对象
    需要的参数:目标对象,增强对象
    */
    public class ProxyFactory {
    /*
    设置三样东西:targetObject,BeforeAdvice,AfterAdvice
    创建代理对象:createProxy()
    */
    private Object targetObject;//目标对象
    private BeforeAdvice beforeAdvice;//前置增强
    private AfterAdvice afterAdvice;//后置增强

    /*
    得到代理对象
    */
    public Object createProxy(){
    /*
    1.三大参数
    */
    ClassLoader loader = this.getClass().getClassLoader();
    Class[] interfaces = targetObject.getClass().getInterfaces();
    InvocationHandler h = new InvocationHandler() {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    /*
    在调用目标对象的方法时会调用这里的内容
    */
    if(beforeAdvice != null){//执行前置增强
    beforeAdvice.before();
    }

    Object result = method.invoke(targetObject,args);//执行目标对象的目标方法

    if (afterAdvice != null){//执行后置增强
    afterAdvice.after();
    }
    return result;//返回目标方法的返回值

    }
    };

    /*
    2.用三大参数得到代理对象
    */
    Object proxyObject = Proxy.newProxyInstance(loader,interfaces,h);
    /*
    3.返回代理对象
    */
    return proxyObject;
    }

    public Object getTargetObject() {
    return targetObject;
    }

    public void setTargetObject(Object targetObject) {
    this.targetObject = targetObject;
    }

    public BeforeAdvice getBeforeAdvice() {
    return beforeAdvice;
    }

    public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
    this.beforeAdvice = beforeAdvice;
    }

    public AfterAdvice getAfterAdvice() {
    return afterAdvice;
    }

    public void setAfterAdvice(AfterAdvice afterAdvice) {
    this.afterAdvice = afterAdvice;
    }
    }

    2. 利用代理工厂实现动态代理
      /*
        利用代理工厂实现动态代理
        1.创建工厂
        2.给工厂设置东西
        --目标对象 setTargetObject(xxx)
        --前置增强 setBeforeAdvice(该接口的实现)
        --后置增强 setAfterAdvice(该接口的实现)
        3.调用createProxy()得到代理对象
        --执行代理对象方法时
            1)执行前置增强的方法
            2)目标对象的目标方法
            3)执行后置增强的方法
         */
    public class Demo1 {

    @Test
    public void fun1(){
    /*
    1.创建工厂
    */
    ProxyFactory factory = new ProxyFactory();
    /*
    2.给工厂设置:目标对象,前置增强,后置增强
    */
    factory.setTargetObject(new manWaiter());
    factory.setBeforeAdvice(new BeforeAdvice() {
    @Override
    public void before() {
    System.out.println("您好");
    }
    });
    factory.setAfterAdvice(new AfterAdvice() {
    @Override
    public void after() {
    System.out.println("再见");
    }
    });
    /*
    3.调用createProxy得到代理对象
    */
    Waiter manWaiter = (Waiter) factory.createProxy();
    /*
    4.调用目标对象的目标方法
    */
    manWaiter.serve();
    }
    }
     
  • 相关阅读:
    Python基础知识(day3)
    前端开发工具Brackets介绍,安装及安装Emme插件时踩过的坑
    AngularJs学习笔记2-控制器、数据绑定、作用域
    AngularJs学习笔记1——总体介绍
    AngularJs学习笔记0——前言
    Oracle常用几种Sql用法
    个人2015年工作计划
    C#语法糖之第六篇: 泛型委托- Predicate<T>、Func<T>
    C#语法糖之第五篇: 泛型委托- Action<T>
    C#语法糖之第三篇: 匿名类 & 匿名方法
  • 原文地址:https://www.cnblogs.com/rachelgarden/p/10640924.html
Copyright © 2011-2022 走看看