JAVA动态代理【理解分析】

**

JAVA动态代理【理解分析】

**

  • 动态代理模式,讲到这里之前必须先讲讲代理模式。java的设计模式的设计思想都来源于生活,代理模式也不例外,用通俗的语言来讲,比如:我们去交电费,交水费,我们没有时间或者实际的水费公司,电费公司太远,或者网点太少,这时候,我们会考虑引入代理商,代理商的职责就是代替我们实际的客户,去代理客户拿着客户的钱,去充值到水费公司,电费公司。这样的一种解决实际问题的设计思想。

采用专业的术语来描述呢,就是我们参考这样的一个设计图:
在这里插入图片描述
实际的委托类提供实际的操作实现,也就是提供钱。代理类即代理商,电费公司通过代理商获取到客户的钱,这样就实现了代理商代理缴费的业务设计。

举例:比亚迪代工苹果手机芯片生产(当然不是特别贴切)
代码示例:
/****
*

  • 手机接口

*/
public interface IMobile {

/**
 * 芯片配件
 * @param number
 * @return
 */
public boolean chip(int number);

}


public class AppleMobile implements IMobile {

    /**
     * 芯片设计
     * @param number
     * @return
     */
    public boolean chip(int number) {
        System.out.println("芯片代工数量:"+number);
        return false;
    }
}
/**
 * BYD代理手机组装,代理人
 */
public class BYDProxy implements IMobile {
    //实际手机厂商-被代理人
    private static AppleMobile appleMobile;

    public BYDProxy(AppleMobile appleMobile){
        this.appleMobile = appleMobile;
    }

    //代理人调用实际厂商的芯片
    public boolean chip(int number) {
        return appleMobile.chip(number);
    }

}
/**
 *
 * 代理模式测试-静态代理
 */
public class ProxyTest {

    public static void main(String[] args) {
        //苹果手机芯片实际设计
        AppleMobile appleMobile = new AppleMobile();

        //BYD进行苹果芯片设计的代理
        BYDProxy  proxy = new BYDProxy(appleMobile);

        //芯片生产,这里代理传入对象必须是苹果手机,也就是代理商只做苹果手机的芯片
        proxy.chip(10);
    }
}
BYDProxy代理商,通过代理实例化苹果手机对象,进行芯片代工
处理结果:
芯片代工数量:10

- 缺点:

  • 该实现也叫静态代理,即每个代理商都是固定的代理一种具体的业务代理,这样不能实现委托类的变化。
  • 该实现也带来,只能做委托人的固定方法,不能做其他的业务增值或者副业,导致能力相对固定。
  • 静态代理,在程序实例化的时候,对象其实就已经创建了,没有实现延迟加载或者叫动态的加载。
    这时候就需要动态代理

**

动态代理

**
动态代理是在程序运行时通过反射机制动态创建的。我们只需要写一个代理类,具体的不同委托人,我们可以实现动态的创建,这样我们就可以实现一个代理商代理多种委托业务的这个能力,同时可以做到能力的增强,实现一些委托业务的处理前加强功能,处理后加强功能。
具体实现方式有2种,JDK原生的动态代理,即invocationHandler对象的实现。第二种为CGlib的动态代理,CGlib是基于net.sf.cglib.proxy包API的开源第三方实现API方式。CGlib相对于JDK原生的动态代理方式呢,JDK原生动态代理对于是实现了接口的对象,可以实现很好的动态实例化,但是对于没有实现接口的对象,如果要实现动态代理,就必须采用CGLib的方式更好一些。

  1. JDK动态代理
/**
 *
 * JDK原生动态代理实现,必须实现InvocationHandler,实现方法invoke,在方法内可以实现代码的方法增强
 * @param <T>
 */
public class JDKDynamicProxy<T>  implements InvocationHandler {

    T target;

    public  JDKDynamicProxy(T target){
      this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //实际方法执行前可以做预处理
        System.out.println("代理执行" +method.getName() + "方法");
        //代理过程中插入监测方法,计算该方法耗时
        Long start = System.currentTimeMillis();
        Object result = method.invoke(target, args);
        Long end = System.currentTimeMillis();
        //实际方法执行后可以做后续处理

        System.out.println("代理执行方法时间:" + (end-start) + "");
        return result;
    }
}
/**
 * JDK 原生的动态代理 测试
 */
public class JdkDynamicProxyTest {

    public static void main(String[] args) {
        //创建苹果手机对象,该对象为实际的对象
        AppleMobile appleMobile = new AppleMobile();

        //创建小米手机对象,该对象为实际的对象
        XiaomiMobile xiaomiMobile = new XiaomiMobile();

        //创建与实际类关联的handler代理类,这里代理商可以生产多种手机的芯片
        InvocationHandler proxy = new JDKDynamicProxy<IMobile>(appleMobile);
        InvocationHandler xiaomiProxy = new JDKDynamicProxy<IMobile>(xiaomiMobile);

        //创建一个代理对象来代理appMobile类,代理对象的每个执行方法都会替换invoke方法
        IMobile mobile = (IMobile) Proxy.newProxyInstance(IMobile.class.getClassLoader(),new Class<?>[]{IMobile.class},proxy);
        IMobile xmMobile = (IMobile) Proxy.newProxyInstance(IMobile.class.getClassLoader(),new Class<?>[]{IMobile.class},xiaomiProxy);

        //动态代理执行芯片
        mobile.chip(10);
        //代理小米手机芯片生产
        xmMobile.chip(30);

    }
}
  1. CGLib动态代理
    引入cglib的第三方库:
 <dependencies>
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>2.2.2</version>
            </dependency>
        </dependencies>
/****
 *
 * CGlib动态代理实现方式
 * CGlib为第三方动态代理API,必须实现MethodInterceptor
 */
public class CglibDynamicProxy<T>  implements MethodInterceptor {


    public Object getInstance(Class<T> clazz){
        Enhancer enhancer = new Enhancer();

        enhancer.setSuperclass(clazz);

        enhancer.setCallback(this);

        return enhancer.create();

   }


    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("代码增强,CGlib动态代理执行前.....");


        return methodProxy.invokeSuper(o,objects);
    }
}
/**
 * CGlib的动态代理 测试
 */
public class CGlibDynamicProxyTest {

    public static void main(String[] args) {

        //创建苹果手机对象,该对象为实际的对象
        AppleMobile appleMobile = new AppleMobile();

        //创建小米手机对象,该对象为实际的对象
        XiaomiMobile xiaomiMobile = new XiaomiMobile();

        CglibDynamicProxy proxy = new CglibDynamicProxy();

        IMobile appMobile = (IMobile) proxy.getInstance(appleMobile.getClass());
        IMobile xiaoMobile = (IMobile) proxy.getInstance(xiaomiMobile.getClass());

        appMobile.chip(100);
        xiaoMobile.chip(50);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值