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);
}
}

Java高级特性—反射和动态代理的更多相关文章

  1. Java高级特性——反射机制(第二篇)

    在Java高级特性——反射机制(第一篇)中,写了很多反射的实例,可能对于Class的了解还是有点迷糊,那么我们试着从内存角度去分析一下. Java内存 从上图可以看出,Java将内存分为堆.栈.方法区 ...

  2. Java高级特性——反射机制(第一篇)

    ——何为动态语言,何为静态语言?(学习反射知识前,需要了解动态语言和静态语言) 动态语言 >是一类在运行时可以改变其结构的语言,例如新的函数.对象.甚至是代码可以被引进,已有的函数可以被删除或者 ...

  3. Java基础之反射和动态代理

    1,反射是依赖于Class对象,然后根据Class对象,去操作该类的资源的.Class对象是发射的基石! 问题1:人这类事物用什么表示?汽车这类事物用什么表示>计算机文件用什么表示?有如此多的事 ...

  4. java 27 - 9 反射之 动态代理的概述和实现

    代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象. 举例:春季回家买票让人代买 动态代理: 在程序运行过程中产生的这个对象 而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以 ...

  5. Java高级特性——反射机制(第三篇)

    获取类运行时的结构 通过反射获取运行时类的完整结构 Field.Method.Constructor.Superclass.Interface.Annotation >实现的全部接口 >所 ...

  6. Java高级特性——反射

    感谢原文作者:peter_RD_nj 原文链接:https://www.jianshu.com/p/9be58ee20dee 注意:同一个类在JVM中只存在一份字节码对象 概述 定义 JAVA反射机制 ...

  7. java 27 - 10 反射之 动态代理的代码实现

    为什么要写动态代理类? 例子: 如果现在想做个登陆注册的功能.用户可以执行登陆.注册.添加.删除这些功能. 但是,有些功能是要有一定权限才可以执行的. 而现在已经有了个用户类的接口和该类的实现类了,但 ...

  8. JAVA高级特性反射和注解

    反射: 枚举反射泛型注解.html34.3 KB 反射, 主要是指通过类加载, 动态的访问, 检测和修改类本身状态或行为的一种能力, 并能根据自身行为的状态和结果, 调整或修改应用所描述行为的状态和相 ...

  9. Java高级特性——反射机制(完结)——反射与注解

    按照我们的学习进度,在前边我们讲过什么是注解以及注解如何定义,如果忘了,可以先回顾一下https://www.cnblogs.com/hgqin/p/13462051.html. 在学习反射和注解前, ...

随机推荐

  1. PHP:在class中定义常量注意事项

    一.不能在成员函数中定义常量,否则会引发诡异地语法错误 syntax error, unexpected 'CONST' (T_CONST) 示例 /* 错误的方式 */ class A { publ ...

  2. 【BZOJ 5048 塌陷的牧场】

    Time Limit: 25 Sec  Memory Limit: 256 MBSubmit: 77  Solved: 34[Submit][Status][Discuss] Description ...

  3. hashCode()方法和equals方法的重要性。

    在Object中有两个重要的方法:hashCode()和equals(Object obj)方法,并且当你按ctrl+alt+s时会有Generator hashCode()和equals().我们不 ...

  4. 高级数据查询SQL语法

    接上一篇关系数据库SQL之基本数据查询:子查询.分组查询.模糊查询,主要是关系型数据库基本数据查询.包括子查询.分组查询.聚合函数查询.模糊查询,本文是介绍一下关系型数据库几种高级数据查询SQL语法, ...

  5. ASIHttprequest-创建同步请求

    ASIHttprequest-创建同步请求 当你发送一个同步请求后,该请求会在当前的应用主线程中运行并获取程序的控制权限,也就说你的程序处于锁定的状态,在这个期间,你进行不了任何的操作,直到该请求返回 ...

  6. 编译gdb 报错 No module named gdb.frames

    将源码目录下的python模块拷贝到指定目录即可 cd /root/gdb-7.12/ cp -rp gdb/python/lib/gdb /usr/local/share/gdb/python/ 编 ...

  7. lxml.html删除节点树和tag对

    # encoding: utf-8import StringIO from apihelper import info, info_savefrom lxml import etree, htmlfr ...

  8. git的使用03

    之前我们写的都是将代码存在本地,我们还可以将代码github官网上,放在github的服务器上去托管

  9. Mongodb的学习整理(下)

    聚合 aggregate 聚合(aggregate)主要用于计算数据,类似sql中的sum().avg() 语法 db.集合名称.aggregate([{管道:{表达式}}]) 管道 管道在Unix和 ...

  10. react setState里的作用域

    从接触racet开始,我们就认识了setState,它是对全局变量进去更新的一个重要方法, 不仅可以更新数据,还能在更新后执行方法时直接调用刚刚更新的数据 今天碰到的问题就在于它的作用域的先后问题 先 ...