package javaenhance.src.cn.itcast.day3;

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.ArrayList;

import java.util.Collection;

public class ProxyTest {

/**

* @param args

*/

public static void main(String[] args) throws Exception{

// TODO Auto-generated method stub

//接收两个参数,一个是后边参数的字节码的加载器,一个是所要实现代理的接口的字节码

Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);

System.out.println(clazzProxy1.getName());//打印代理的名字     $Proxy0

System.out.println("----------begin constructors list----------");

/*想打印出如下格式:

* $Proxy0()

$Proxy0(InvocationHandler,int)*/

Constructor[] constructors = clazzProxy1.getConstructors();//获取代理的构造函数

for(Constructor constructor : constructors){

String name = constructor.getName();//获取代理的构造函数的name

StringBuilder sBuilder = new StringBuilder(name);

sBuilder.append('(');

Class[] clazzParams = constructor.getParameterTypes();//获取代理的构造函数的参数

for(Class clazzParam : clazzParams){

sBuilder.append(clazzParam.getName()).append(',');

}

if(clazzParams!=null && clazzParams.length != 0)//稳妥的判断是否是一个参数,不是就删掉最后的,

sBuilder.deleteCharAt(sBuilder.length()-1);

sBuilder.append(')');

System.out.println(sBuilder.toString());    //$Proxy0(java.lang.reflect.InvocationHandler)

}

System.out.println("----------begin methods list----------");

/*$Proxy0()

$Proxy0(InvocationHandler,int)*/

Method[] methods = clazzProxy1.getMethods();//获取代理身上的方法

for(Method method : methods){

String name = method.getName();

StringBuilder sBuilder = new StringBuilder(name);

sBuilder.append('(');

Class[] clazzParams = method.getParameterTypes();

for(Class clazzParam : clazzParams){

sBuilder.append(clazzParam.getName()).append(',');

}

if(clazzParams!=null && clazzParams.length != 0)

sBuilder.deleteCharAt(sBuilder.length()-1);

sBuilder.append(')');

System.out.println(sBuilder.toString());

}

System.out.println("----------begin create instance object----------");

//Object obj = clazzProxy1.newInstance();

//方式一:通过接口的子类创建对象

Constructor constructor =

clazzProxy1.getConstructor(InvocationHandler.class);

//获取代理身上的构造函数

//创建内部类MyInvocationHandler1,目的是传递给代理的构造器

class MyInvocationHandler1 implements InvocationHandler{

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

// TODO Auto-generated method stub

return null;

}

}

//方式二:匿名内部类

Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHandler1());

System.out.println(proxy1);//没有错误

proxy1.clear();//没有错误

//proxy1.size();报错,因为,代理调用size方法,其实是调用了MyInvocationHandler1中的invoke,他的返回值是null

//System.out.println("111111111111111");//调试用的

//用了匿名内部类的方法实现

Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler(){

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

return null;

}

});

/*下边这部分代码非常重要和精辟*/

final ArrayList target = new ArrayList();

Collection proxy3 = (Collection)getProxy(target,new MyAdvice());

proxy3.add("zxx");

proxy3.add("lhm");

proxy3.add("bxd");

System.out.println(proxy3.size());

System.out.println(proxy3.getClass().getName());

}

private static Object getProxy(final Object target,final Advice advice) {

//方式三,newProxyInstance这个方法需要三个参数,可以直接创建target的代理对象

Object proxy3 = Proxy.newProxyInstance(

target.getClass().getClassLoader(),

/*new Class[]{Collection.class},*/

//获取target上的接口

target.getClass().getInterfaces(),

new InvocationHandler(){

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

/*long beginTime = System.currentTimeMillis();

Object retVal = method.invoke(target, args);

long endTime = System.currentTimeMillis();

System.out.println(method.getName() + " running time of " + (endTime - beginTime));

return retVal;*/

//把上边的代码封装到一个类中,让后调用该类的方法,就实现了方法的封装

advice.beforeMethod(method);

Object retVal = method.invoke(target, args);

advice.afterMethod(method);

return retVal;

}

}

);

return proxy3;

}

}

/*$Proxy0

----------begin constructors list----------

$Proxy0(java.lang.reflect.InvocationHandler)

----------begin methods list----------

hashCode()

equals(java.lang.Object)

toString()

add(java.lang.Object)

contains(java.lang.Object)

isEmpty()

size()

toArray()

toArray([Ljava.lang.Object;)

addAll(java.util.Collection)

iterator()

remove(java.lang.Object)

clear()

containsAll(java.util.Collection)

removeAll(java.util.Collection)

retainAll(java.util.Collection)

getProxyClass(java.lang.ClassLoader,[Ljava.lang.Class;)

newProxyInstance(java.lang.ClassLoader,[Ljava.lang.Class;,java.lang.reflect.InvocationHandler)

isProxyClass(java.lang.Class)

getInvocationHandler(java.lang.Object)

getClass()

notify()

notifyAll()

wait(long)

wait(long,int)

wait()

----------begin create instance object----------

null

到传智播客来学习啦!

从传智播客毕业上班啦!

add running time of 0

到传智播客来学习啦!

从传智播客毕业上班啦!

add running time of 0

到传智播客来学习啦!

从传智播客毕业上班啦!

add running time of 0

到传智播客来学习啦!

从传智播客毕业上班啦!

size running time of 0

3

$Proxy1*/

---------------------------------------------

import java.lang.reflect.Method;

public interface Advice {

void beforeMethod(Method method);

void afterMethod(Method method);

}

---------------------------------------------

package javaenhance.src.cn.itcast.day3;

import java.lang.reflect.Method;

//创建实现Advice接口的子类

public class MyAdvice implements Advice {

long beginTime = 0;

public void afterMethod(Method method) {

// TODO Auto-generated method stub

System.out.println("从传智播客毕业上班啦!");

long endTime = System.currentTimeMillis();

System.out.println(method.getName() + " running time of " + (endTime - beginTime));

}

public void beforeMethod(Method method) {

// TODO Auto-generated method stub

System.out.println("到传智播客来学习啦!");

beginTime = System.currentTimeMillis();

}

}

最新文章

  1. 原创:跳坑指南——微信小程序真机预览跟本地不同的问题
  2. 跳转Activity两种方法
  3. 【BZOJ3504】危桥(最大流)
  4. App lifecycle(UWP深入学习一)
  5. 深入理解include预编译原理
  6. [HDOJ5943]Kingdom of Obsession(最大匹配,思路)
  7. CE_现金银行总行分行设定详解(案例)
  8. C++时间戳转化(涉及GMT CST时区转化)
  9. HINSTANCE数据类型
  10. c++ anonymous namespace -- 匿名空间
  11. SVNKIT的SVNCommitClient的doMkDir的操作
  12. 使用Simple DNS plus 构建自己的DNS
  13. rpm检验是否被改动过
  14. 分布式服务跟踪及Spring Cloud的实现
  15. shift and算法
  16. 20175224 2018-2019-2 《Java程序设计》第五周学习总结
  17. mysql设置环境变量
  18. 部分真验货客户未取进FP IN_SALES_ORDER表有数据,前台规划页面没显示
  19. TP框架中APP_SUB_DOMAIN_DEPLOY什么意思?
  20. 每日英语:Does Evolution Want Us To Be Unhappy?

热门文章

  1. matplotlib常用操作
  2. span元素和div元素的浮动效果
  3. 为何需要apigee edge
  4. Directx11教程(51) 简单的billboard
  5. 免费报名 | 汇聚HBase&大数据最前沿 Apache HBaseConAsia2019盛会火热来袭
  6. [React Native]Promise机制
  7. 【JZOJ4859】【NOIP2016提高A组集训第7场11.4】连锁店
  8. DFS-生日蛋糕
  9. 去除selet标签默认样式
  10. wepy ——$apply