• Java高级特性—反射和动态代理


    1).反射
      通过反射的方式可以获取class对象中的属性、方法、构造函数等,一下是实例:

    2).动态代理
      使用场景:  

        在之前的代码调用阶段,我们用action调用service的方法实现业务即可。
        由于之前在service中实现的业务可能不能够满足当先客户的要求,需要我们重新修改service中的方法,
        但是service的方法不只在我们这个模块使用,在其他模块也在调用,其他模块调用的时候,
        现有的service方法已经能够满足业务需求,所以我们不能只为了我们的业务而修改service,导致其他模块授影响。
        那怎么办呢?
        可以通过动态代理的方式,扩展我们的service中的方法实现,使得在原有的方法中增加更多的业务,
        而不是实际修改service中的方法,这种实现技术就叫做动态代理。

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

      底层是字节码增强技术,常用ASM,CGLIB,javasist等

    3).代理实现流程:
      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方法中,进行新业务的逻辑流程。

      1)原业务接口IBoss

    public interface IBoss {//接口
        int yifu(String size);
    }

      2)原业务实现类

    public class Boss implements IBoss{
        public int yifu(String size){
            System.err.println("天猫小强旗舰店,老板给客户发快递----衣服型号:"+size);
            //这件衣服的价钱,从数据库读取
            return 50;
        }
        public void kuzi(){
            System.err.println("天猫小强旗舰店,老板给客户发快递----裤子");
        }
    }

      3)原业务调用

    public class SaleAction {
        @Test
        public void saleByBossSelf() throws Exception {
            IBoss boss = new Boss();
            System.out.println("老板自营!");
            int money = boss.yifu("xxl");
            System.out.println("衣服成交价:" + money);
        }
    }

      4)代理类

    public static IBoss getProxyBoss(final int discountCoupon) throws Exception {
                    Object proxedObj = Proxy.newProxyInstance(Boss.class.getClassLoader(),
                            new Class[] { IBoss.class }, new InvocationHandler() {
                                public Object invoke(Object proxy, Method method,
                                        Object[] args) throws Throwable {
                                        Integer returnValue = (Integer) method.invoke(new Boss(),
                                                args);// 调用原始对象以后返回的值
                                        return returnValue - discountCoupon;
                                }
                            });
                    return (IBoss)proxedObj;
                }
        }

      5)新业务调用

    public class ProxySaleAction {
            @Test
            public void saleByProxy() throws Exception {
                IBoss boss = ProxyBoss.getProxyBoss(20);// 将代理的方法实例化成接口
                System.out.println("代理经营!");
                int money = boss.yifu("xxl");// 调用接口的方法,实际上调用方式没有变
                System.out.println("衣服成交价:" + money);
            }
    }
  • 相关阅读:
    设计模式(三)--观察者模式
    设计模式(二)--单例模式
    tornado 资源
    复习 网络通信协议
    设置允许远程连接MySQL (Ubuntu为例)
    ubuntu 下安装ssh服务
    Python 运算内建函数
    py知识点拾遗之sort(),sorted(),reverse(),reversed()
    SQLite安装 以及 SQLite header and source version mismatch错误解决 (In debian)
    debian折腾笔记
  • 原文地址:https://www.cnblogs.com/atomicbomb/p/9904361.html
Copyright © 2020-2023  润新知