黑马程序员-动态代理

来源:互联网 发布:淘宝店铺一个好评几分 编辑:程序博客网 时间:2024/06/05 16:57

 ------- android培训、java培训、期待与您交流! ---------

一:代理类产生的需求

l 要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理、等等,而你准备如何做呢?

l 编写一个鱼目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并且在调用方法时加上系统功能的代码

l 如果采取工厂模式和配置文件的方式进行管理,则不需要修改客户端的程序,在配置文件中配置是使用目标类还是代理类,这样以后很容易切换,譬如,想要日志功能时就配置代理类,否则配置目标类,否则配置目标类,这样,增加系统功能会变得很容易,以后运行一段时间后,又想去调用系统功能也很容易。

l 具体应用:AOP面向切面的编程与Spring框架

二: 代理类应用示意图

 三:Java中动态代理类简介

Java动态代理类位于Java.lang.reflect包下,

一般主要涉及到以下两个类:   

一、Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method,Object[] args)。

在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。这个抽象方法在代理类中动态实现。   

二、Proxy:该类即为动态代理类,其中主要包含以下内容:   

 Static Class getProxyClass (ClassLoader loader,Class[] interfaces):

获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。   

newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h):

返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。   

下面通过一个实例来演示动态代理类的工作原理:

 

我们现在要得到ArrayList的代理类的一个实例对象

                     抽象类Advice

import java.lang.reflect.Method;public interface Advice{   void beforeMethod(Method method);   void afterMethod(Method methd);}


用户可能要添加的系统功能添加到这里         即:实现这个抽象类

import java.lang.reflect.Method;public class MyAdvice implements Advice{     long beginTime=0; public void afterMethod(Method method) {        System.out.println("去黑马学习了"); long endTime=System.currentTimeMillis(); System.out.println(method.getName()+"running time"+(endTime-beginTime)); } public void beforeMethod(Method method){     System.out.println("从黑马毕业了"); beginTime=System.currentTimeMillis(); }}


                                                     利用目标类target与系统功能(已经封装在Advice)产生带有用户自定义功能的代理类arraylist

package cn.itcatst.day3;import java.lang.reflect.Proxy;import java.util,Collecttion;public class ProxyTest{       public static void main(String[]args)   {   //   //Class Proxy3=Proxy.getProxyClass(Collection.class.getClassLoader(),Collecttion.class);
            //getProxy()函数已经经过抽取   Collection arraylist=Object getProxy(final Object target,final Advice advvice)  //两个个参数的意思分别为:target要被代理的类,advice用户自定义的系统功能
            {Collection proxy3=Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterface(),new InvocationHandler(){   public Object invoke(Object proxy,Method method,Object[]args)                                 //invoke的三个参数:本代理类对象、要调用目标类的方法、给 要调用的目标类的方法的参数
                  throws Throwable  {  advice.beforeMethod(method);//系统功能  Object retVal=method.invoke(target,args);//目标类功能  advice.afterMethod(method);//系统功能
  return retVal;//返回目标类的方法的返回值  }};)
                                                                          三个参数分别为:产生代理类的的类加载器、代理类要实现的类、InvocationHandle匿名内部类return proxy3; }   }}
这样 用户可以动态的定义代理类的功能又不失去目标类的功能  来满足不断变化的需求