欧博allbet网址:大型Java进阶专题(六)设计模式之署理模式

admin 2周前 (09-07) 科技 146 3

署理模式

前言

又最先我的专题了,又阻滞了一段时间了,加油继续吧。都知道 SpringAOP 是用署理模式实现,到底是怎么实现的?我们来一探事实,而且自己仿真手写还原部门细节。

署理模式的应用

在生活中,我们经常见到这样的场景,如:租房中介、售票黄牛、婚介、经纪人、快递、 事务署理、非侵入式日志监听等,这些都是署理模式的现实体现。署理模式(Proxy Pattern)的界说也异常简朴,是指为其他工具提供一种署理,以控制对这个工具的接见。 署理工具在客服端和目的工具之间起到中介作用,署理模式属于结构型设计模式。使用 署理模式主要有两个目的:一珍爱目的工具,二增强目的象。下面我们来看一下署理 模式的类结构图:

Subject 是顶层接口,RealSubject 是真实工具(被署理工具),Proxy 是署理工具,代 理工具持有被署理工具的引用,客户端挪用署理工具方式,同时也挪用被署理工具的方 法,但是在署理工具前后增添一些处置。在代码中,我们想到署理,就会理解为是代码 增强,实在就是在原本逻辑前后增添一些逻辑,而挪用者无感知。署理模式属于结构型 模式,有静态署理和动态署理。

静态署理

举个例子:人到了适婚年龄,怙恃总是迫在眉睫希望早点抱孙子。而现在社会的人在各 种压力之下,都选择晚婚晚育。于是着急的怙恃就最先四处为自己的子女相亲,比子女 自己还着急。这个相亲的历程,就是一种我们人人都有份的署理。来看代码实现: 

/**
 * 人许多行为,要谈恋爱
 */
public interface Person {
    void findLove();
}


/**
 * 儿子需要找工具
 */
public class Son implements Person {

    @Override
    public void findLove() {
        System.out.println("事情没时间!");
    }
}

/**
 * 父亲署理儿子 先帮物色工具
 */
public class Father{

    private Son son;

    //署理工具持有 被署理工具的应用 但没办法扩展
    private Father(Son son) {
        this.son = son;
    }

    private void findLove() {
        //before
        System.out.println("怙恃帮物色工具");
        son.findLove();
        //after
        System.out.println("双方同意来往!");
    }

    //测试代码
    public static void main(String[] args) {
        Son son = new Son();
        Father father = new Father(son);
        father.findLove();
    }
}

动态署理

动态署理和静态对比基本思路是一致的,只不过动态署理功效加倍壮大,随着营业的扩 展顺应性更强。若是还以找工具为例,使用动态署理相当于是能够顺应庞大的营业场景。 不仅仅只是父亲给儿子找工具,若是找工具这项营业生长成了一个产业,进而泛起了媒 婆、婚介所等这样的形式。那么,此时用静态署理成本就更大了,需要一个加倍通用的 解决方案,要知足任何独身人士找工具的需求。我们升级一下代码,先来看 JDK 实现方式:

JDK 实现方式

建立牙婆(婚介)JDKMeipo 类:

package com.study;

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


public class JdkMeipo implements InvocationHandler {
  	//持有被署理工具的引用
    Object target;

    public Object getInstance(Object target){
        this.target =target;
        Class<?> aClass = target.getClass();
        return Proxy.newProxyInstance(aClass.getClassLoader(),aClass.getInterfaces(),this);
    }
  
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object object = method.invoke(this.target,args);
        after();
        return object;
    }

    private void before() {
        System.out.println("我是婚介,帮你物色工具");
    }

    private void after() {
        System.out.println("已找到,若是合适就最先");
    }
}

建立独身客户

package com.study;

public class Customer implements Person{

    @Override
    public void findLove() {
        System.out.println("我要找白富美");
    }
}

测试代码

package com.study;

public class DemoTest {
    public static void main(String[] args) {
        Person person = (Person) new JdkMeipo().getInstance(new Customer());
        person.findLove();
    }
}

执行效果

Jdk署理的原理

不仅知其然,还得知其以是然。既然 JDK Proxy 功效云云壮大,那么它是若何实现的呢? 我们现在来探讨一下原理。 我们都知道 JDK Proxy 接纳字节重组,重新生的工具来替换原始的工具以到达动态署理 的目的。JDK Proxy 天生工具的步骤如下:

1.拿到署理工具的应用,并获取它的所有接口,反射获取。

2.通过JDK proxy 类重新天生一个新的类,同时新的类要实现被署理类所有实现的接口。

3.动态天生Java代码,把新加的营业逻辑方式由一定的逻辑代码去挪用(在代码中体现)。

4.编译重新天生Java代码.class

5.再重新加载的JVM中
以上这个历程就叫字节重组。

CGLib实现方式

简朴看一下 CGLib 署理的使用,还是以牙婆为例,建立 CglibMeipo 类:

package com.study;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CGlibMeipo implements MethodInterceptor {
    Object target;
    public Object getInstance(Class<?> aClass){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(aClass);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        before();
        Object invokeSuper = methodProxy.invokeSuper(o, objects);
        after();
        return invokeSuper;
    }

    private void after() {
        System.out.println("已找到,若是合适就最先");
    }

    private void before() {
        System.out.println("我是婚介,帮你物色工具");
    }
}

测试挪用

package com.study;

public class DemoTest {
    public static void main(String[] args) {
        //Person person = (Person) new JdkMeipo().getInstance(new Customer());
        Person person = (Person) new CGlibMeipo().getInstance(Customer.class);
        person.findLove();
    }
}

执行效果:(CGLib署理的工具是不需要实现任何接口的,他是通过动态继续目的工具实现的动态署理。)

CGLib 动态署理执行署理方式效率之以是比 JDK 的高是因为 Cglib 接纳了 FastClass 机 制,它的原理简朴来说就是:为署理类和被署理类各天生一个 Class,这个 Class 会为代 理类或被署理类的方式分配一个 index(int 类型)。这个 index 当做一个入参,FastClass 就可以直接定位要挪用的方式直接进行挪用,这样省去了反射挪用,以是挪用效率比 JDK 动态署理通过反射挪用高。

CGLib 和 JDK 动态署理对比

1.JDK 动态署理是实现了被署理工具的接口,CGLib 是继续了被署理工具。

2.JDK 和 CGLib 都是在运行期天生字节码,JDK 是直接写 Class 字节码,CGLib 使用 ASM 框架写 Class 字节码,Cglib 署理实现更庞大,天生署理类比 JDK 效率低。

3.JDK 挪用署理方式,是通过反射机制挪用,CGLib 是通过 FastClass 机制直接挪用方式, CGLib 执行效率更高。

,

欧博开户网址

欢迎进入欧博开户网址(Allbet Gaming):www.aLLbetgame.us,欧博网址开放会员注册、代理开户、电脑客户端下载、苹果安卓下载等业务。

allbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:欧博allbet网址:大型Java进阶专题(六)设计模式之署理模式

网友评论

  • (*)

最新评论

  • usdt钱包官方下载 2021-05-30 00:01:58 回复

    usdt自动充提菜宝钱包www.caibao.it是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。这个文,很绝哦

    2
  • 新2会员手机管理端 2021-09-07 00:01:32 回复

    〔<记者锺智凯>/(〖台北报〗导)〕 谢忻[昨(出席)哈[孝远婚宴,{先前曾爆哈孝远把阿}翔、“ 谢忻[都找来了”,〖这让闹出不伦恋〗的2「人十分尴尬」,{「对此」谢}忻表示她不担心,“如果真的婚宴”碰到了,‘她还是会打招呼’, 也透露〖目〗前[(经济){状况}。新发现的宝藏文

    3

站点信息

  • 文章总数:1763
  • 页面总数:0
  • 分类总数:8
  • 标签总数:1613
  • 评论总数:2585
  • 浏览总数:212229