黑马程序员--Java高新(10)_动态代理和AOP编程

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一, 动态的核心

动态代理的两个核心,Proxy 和 InvocationHandler,都是Java.lang.reflect包下的接口类;由此也可以看出动态代理是反射的高级应用!

代理与反射的关系如何体现?从代理的建立过程的构建方法及其参数可见一斑:

1,代理最核心的Handler的唯一方法invoke()的核心参数Method method,是一个Class类型,并且在代理调用时,invoke到target对象来返回retval.

2,代理的构造方法参数, 也就是牛X的newProxyInstance()方法的前两个参数, 是目标接口的ClassLoader 和 Interface[ ],也是通过接口Class对象反射get到;

二, 代理的调用方法

Object invoke(Object proxy, Method method,Object[] args)  方法,该方法 在代理实例上处理方法调用并返回结果。

每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。

三个参数的意思是:

Object proxy           在其上调用方法的代理实例

Method method     对应于在代理实例上调用的接口方法的Method 实例

Object[] args         包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为null

三, 代理实例的创建

方法一.1,通过Proxy.getProxyClass()方法创建若干接口的Class文件,

2,通过Class文件可以得到其构造方法

3,最后通过构造方法实例的newInstance方法得到代理实例

方法二.,通过Proxy的newProxyInstance() 方法,直接返回一个带有代理类的指定调用处理程序的代理实例,

它由指定的类加载器定义,并实现指定的接口

该方法的参数列表是:

ClassLoader  loader,    指定一个类加载器用于加载指定的接口

Class<?>[] interfaces,   给出需要创建代理实例的接口

InvocationHandlerh,      给出代理实例的调用处理程序实现的接口

显而易见,方法二是对代理逻辑的代码重新封装,有利于编写和管理三大代理构建参数,使大家可以集中精力去处理invoke()方法, target对象,切面信息(Advice),实现AOP编程;

以下为Proxy实例的建立,和进一步AOP编程的应用:

static void clazzProxy()throws Exception{  

       ClassclazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader() ,Collection.class);  

       System.out.println(clazzProxy1.getName());  

       System.out.println("---------------constructorslist--------------");  

       Constructor[]constructors = clazzProxy1.getConstructors();  

       for(Constructorconstructor : constructors){  

              Stringname = constructor.getName();  

              StringBuildersBuilder = new StringBuilder(name);  

              sBuilder.append('(');  

              Class[]clazzParams = constructor.getParameterTypes();  

              for(ClassclazzParam:clazzParams){  

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

              }  

              if(clazzParams.length==0)  

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

              sBuilder.append(')');  

              System.out.println(sBuilder);  

       }  

       System.out.println("-------------begincerate instance --------------");  

       Constructorconstructor = clazzProxy1.getConstructor(InvocationHandler.class);  

       classMyInvocationHandler1 implements InvocationHandler{  

              @Override  

              publicObject invoke(Object arg0, Method arg1, Object[] arg2)  

                            throwsThrowable {  

                     //TODO Auto-generated method stub   

                     returnnull;  

              }  

       };  

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

       System.out.println("xxxxxxxxx"+proxy1.toString());//没有返回值的方法可以调用。有返回值的方法,可以调用   

       //proxy1.size();//不能调用,因为其没有指定目标   

       proxy1.clear();//可以调用   

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

              ArrayListtarget = new ArrayList();  

              @Override  

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

                            throwsThrowable {  

                     longbeginTime = System.currentTimeMillis();  

                     ObjectretVal = method.invoke(target,args);  

                     longendTime = System.currentTimeMillis();  

                     System.out.println(method.getName()+"运行时间"+(endTime-beginTime));  

                     returnretVal;  

              }  

       });  

       proxy2.add("zxx");  

       proxy2.add("Java01");  

       proxy2.add("Java");  

       proxy2.size();  

       Collectionproxy3 = (Collection)Proxy.newProxyInstance(  

                     Collection.class.getClassLoader(),  

                     newClass[]{Collection.class},  

                     newInvocationHandler(){  

                            ArrayListtarget = new ArrayList();  

                            @Override  

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

                                          throwsThrowable {  

                                   longbeginTime = System.currentTimeMillis();  

                                   ObjectretVal = method.invoke(target,args);  

                                   longendTime = System.currentTimeMillis();  

                                   System.out.println(method.getName()+"运行时间:"+(endTime-beginTime));  

                                   returnretVal;  

                            }  

                     }  

                     );  

       proxy3.add("Java01");  

       proxy3.add("Java02");  

       proxy3.add("Java03");  

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

}  

}
时间: 2024-12-25 06:50:29

黑马程序员--Java高新(10)_动态代理和AOP编程的相关文章

黑马程序员——java高新---注解、泛型等

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.注解 什么是注解? 答:对于过时的语句,java会提示过时了,通过@SuppressWarnings("Deprecation")可以在DOS命令行中取消提示,但Eclipse无法取消.这就是注解,相当于标记.编译器.开发工具.javac通过反射获得注解里的内容,进而明确应该做什么.不应该做什么.注解可以加在包.类.属性.方法.参数及局部变量之上.一个注解就是一个类. java.

黑马程序员——java高新---JDK1.5新特性和反射

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.JDK1.5新特性 ——>静态导入 import和import static之间的区别: 1.import是导入一个类或某个包中所有的类. 2.import static是导入一个类中的某个静态成员或所有的静态成员. 注意: 1.当导入的两个类中有同名成员时,需要在成员前加上相应的类名. 2.当类名重名时,需要指定具体的包名. 3.方法重名时,需要指定具体所属的对象或者类. 代码示例: 1

动态代理和AOP切面编程

import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /* * 动态代理和AOP切面编程 */ //定义一个接口 interface Person { void eat(); void breath(); } // 定义一个实现接口的实现类,即为被代理类 class Student implements Person { @Overr

黑马程序员-java 7K面试题之交通灯管理系统

------- android培训.java培训.期待与您交流! -------- 交通灯管理系统 模拟实现十字路口的交通灯管理系统逻辑,具体需求如下: 1. 异常随机生成按照各个路线行驶的车辆. 例如: 由南向而来去往北向的车辆----直行车辆 由西向而来去往南向的车辆----右转车辆 由东向而来去往南向的车辆----左转车辆 .......  ...... 2. 信号灯忽略黄灯,只考虑红灯和绿灯. 3. 应该考虑左转车辆控制信号灯,右转车辆不受信号灯控制. 4. 具体信号灯控制逻辑与现实

黑马程序员——Java高新技术代理

代理 普通代理 很多时候,我们使用别人代码往往会发现别人代码的功能并不是十分符合我们的需求,调用别人的方法的时候,总是先new一个对象,然后我们的前处理做完,然后调用别人代码的方法,再加入后处理,这样做往往十分麻烦.代理就为其他类提供了一种控制其对象的方法.代理类和委托类必须实现同一个接口,这样代理类才能在需要的时候代替委托类对象,执行委托类的方法. interface Solution{ public void doSomething(); } //委托类Demo实现了接口 class Dem

黑马程序员——java基础——多线程

 黑马程序员--java基础--多线程 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 进程:是一个正在执行中的程序.每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控制单元. 线程:就是进程中的一个独立的控制单元.线程在控制着进程的执行.一个进程中至少有一个线程. 一个进程至少有一个线程在运行,当一个进程中出现多个线程时,就称这个应用程序是多线程应用程序,每个线程在栈区中都有自己的执行空间,自己的方法区.自己的变量.

黑马程序员---Java多线程

---------------------- Android开发.java培训.期待与您交流! ---------------------- 线程与进程是程序运行中体现的两个名词,它包含这不同的程序域.进程指的是一个正在运行的程序,如:360,QQ运行时就是不同的两个进程.当你打开windows任务管理器时,看到的每个进程就是此时windows中正在运行的程序.线程则就是进程中的一个个独立的控制单元,线程控制着进程的执行,也就是说每个正在运行的程序中就包括着很多的线程. 主线程:Java虚拟机运

黑马程序员——java基础——反射

 黑马程序员--java基础--反射 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 反射 其实就是动态加载一个指定的类,并获取该类中的所有的内容.而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员. 反射就是把Java类中的各种成分映射成相应的java类. 简单说:反射技术可以对一个类进行解剖. 反射的基石-->Class类 1.java中的类是用来描述一类事物的共性,该类事物有什么属性,没有什么属性

黑马程序员–Java之多线程09

黑马程序员–Java之多线程09 一.线程和进程 在Java中,并发机制非常重要,程序员可以在程序中执行多个线程,每一个线程完成一个功能,并与其他线程并发执行,这种机制被称为多线程.多线程就是指一个应用程序中有多条并发执行的线索,每条线索都被称作一个线程,它们会交替执行,彼此间可以进行通信.多线程是非常复杂的机制,在每个操作系统中的运行方式也存在差异,window操作系统是多任务操作系统,它以进程为单位.一个进程是一个包含有自身地址的程序,每个独立执行的程序都称为进程,也就是正在执行的程序.系统