zoukankan      html  css  js  c++  java
  • Java反射和动态代理

    反射

    通过反射的方式Class.forName(“com.ahu.Person”)可以获取class对象的实例以及其中的属性、方法、构造函数等

    动态代理

    动态代理:在不修改原业务的基础上,基于原业务方法,进行重新的扩展,实现新的业务

    例子:

    1、 旧业务

    买家调用action,购买衣服,衣服在数据库的标价为50元,购买流程就是简单的调用。

    2、 新业务

    在原先的价格上可以使用优惠券,但是这个功能在以前没有实现过,我们通过代理类,代理了原先的接口方法,在这个方法的基础上,修改了返回值。

    代理实现流程:

    1、 书写代理类和代理方法,在代理方法中实现代理Proxy.newProxyInstance

    2、 代理中需要的参数分别为:被代理的类的类加载器soneObjectclass.getClassLoader(),被代理类的所有实现接口new Class[] { Interface.class },句柄方法new InvocationHandler()

    3、 在句柄方法中复写invoke方法,invoke方法的输入有3个参数Object proxy(代理类对象), Method method(被代理类的方法),Object[] args(被代理类方法的传入参数),在这个方法中,我们可以定制化的开发新的业务。

    4、 获取代理类,强转成被代理的接口

    5、 最后,我们可以像没被代理一样,调用接口的认可方法,方法被调用后,方法名和参数列表将被传入代理类的invoke方法中,进行新业务的逻辑流程。

    原业务接口IBoss

    1 /**
    2  * 这是一个业务的接口,这个接口中的业务就是返回衣服的价格
    3  * 4  *
    5  */
    6 public interface IBoss {//接口
    7     int yifu(String size);
    8 }

    原业务实现类Boss

     1 /**
     2  * 实现了卖衣服的接口
     3  * 自定义了自己的业务,卖裤子
     4  * @author wilson
     5  *
     6  */
     7 public class Boss implements IBoss{
     8     public int yifu(String size){
     9         System.err.println("天猫小强旗舰店,老板给客户发快递----衣服型号:"+size);
    10         //这件衣服的价钱,从数据库读取
    11         return 50;
    12     }
    13     public void kuzi(){
    14         System.err.println("天猫小强旗舰店,老板给客户发快递----裤子");
    15     }
    16 }

    原业务调用

     1 public class SaleAction {
     2     /**
     3      * 不使用代理,直接调用方法
     4      * 方法中规定什么业务,就只能调用什么业务,规定什么返回值,就只能输出什么返回值
     5      */
     6     @Test
     7     public void saleByBossSelf() throws Exception {
     8         IBoss boss = new Boss();
     9         System.out.println("老板自营!");
    10         int money = boss.yifu("xxl");// 老板自己卖衣服,不需要客服,结果就是没有聊天记录
    11         System.out.println("衣服成交价:" + money);
    12     }
    13 }

    代理类

     1 public class ProxyBoss {
     2     /**
     3      * 对接口方法进行代理
     4      */
     5     @SuppressWarnings("unchecked")
     6     public static <T> T getProxy(final int discountCoupon,
     7             final Class<?> interfaceClass, final Class<?> implementsClass)
     8             throws Exception {
     9         return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),
    10                 new Class[] { interfaceClass }, new InvocationHandler() {
    11                     public Object invoke(Object proxy, Method method,
    12                             Object[] args) throws Throwable {
    13                         Integer returnValue = (Integer) method.invoke(
    14                                 implementsClass.newInstance(), args);// 调用原始对象以后返回的值
    15                         return returnValue - discountCoupon;
    16                     }
    17                 });
    18     }
    19 }

    新业务调用

     1 /**
     2  * 什么是动态代理? 简单的写一个模板接口,剩下的个性化工作,好给动态代理来完成!
     3  */
     4 public class ProxySaleAction {
     5     
     6     /**
     7      *使用代理,在这个代理中,只代理了Boss的yifu方法
     8      *定制化业务,可以改变原接口的参数、返回值等
     9      */
    10     @Test
    11     public void saleByProxy() throws Exception {
    12         IBoss boss = ProxyBoss.getProxy(10,IBoss.class,Boss.class);// 将代理的方法实例化成接口
    13         //IBoss boss = new Boss();// 将代理的方法实例化成接口
    14         System.out.println("代理经营!");
    15         int money = boss.yifu("xxl");// 调用接口的方法,实际上调用方式没有变
    16         System.out.println("衣服成交价:" + money);
    17     }
    18 }
  • 相关阅读:
    InnoDB存储引擎介绍-(2)redo和undo学习
    InnoDB存储引擎介绍-(1)InnoDB存储引擎结构
    MySQL共享表空间概念
    MySQL压力测试(1)-mysqlslap
    MySQL5.6复制技术(4)-MySQL主从复制过滤参数
    MySQL5.6复制技术(3)-MySQL主从复制线程状态转变
    MySQL5.6复制技术(2)-主从部署以及半同步配置详细过程
    vue 子组件 $emit方法 调用父组件方法
    es聚合后排序
    java比较两个小数的大小
  • 原文地址:https://www.cnblogs.com/ahu-lichang/p/6739459.html
Copyright © 2011-2022 走看看