A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© tfy 中级黑马   /  2013-1-3 23:41  /  2131 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

什么是动态代理
分类: 评论(2) 举报


import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;


/**
* 代理模式至少需要实现两个类,一个代理类,一个被代理类(都要实现共有接口)。
* 动态代理之所以称为动态,是因为代理类在运行时由Proxy类产生,
* 这就大大减少了需要我们手工设计代理类的数量。
*在实际应用中,Proxy通过类装载器和需要实现的接口来产生代理类,
*即Proxy.getProxyClass(ClassLoader, Class[]),返回为代理类的Class实例。
*一般而言,该方法由InvocationHandler的实现类中的方法来调用,
*可以取这样的名字:getProxyObject,该方法使用Proxy.getProxyClass后
*(此时两个入口参数可以用realObject.getClass.getClassLoader()
*以及realObject.getClass.getInterfaces()两个方法得到,
*realObject指被代理类实例,一般由InvocationHandler的实现类的构造函数注入),
*进一步使用Class中的getConstructor(new Class[] { InvocationHandler.class}).newInstance(new Object[] { this })
*来得到代理类的实例(或者合并这两个方法,
*用Proxy.newProxyInstance(realObject.getClass.getClassLoader(), realObject.getClass.getInterfaces(),this)方法)
*。但是必须注意代理类的实现是由Proxy完成,与InvocationHander的实现类毫无关系,
*InvocationHander的实现类只是通过代理类的构造函数注入后实现了对代理类中方法调用的拦截。
*InvocationHander的实现类需要保留一个指向被代理类的引用(或称句柄、指针),
*该被代理类一般通过InvocationHandler的实现类的构造函数注入,也可以用set方法,
*一般可以取为realObject。则在InvocationHandler接口的invoke方法中,
*对于realObject中相应方法的直接调用是用method.invoke(realObjet, args )实现的,
*其中method和args直接由invoke方法中的输入参数给出。
*
*好了先让我们俩了解什么是代理
*/

//AOP面向切面的编程
public class BeanFactory {
    //动态代理入门
    public static void main(String[] args) throws Exception {
        //首先我们先让JVM生成一个代理类
        Class clazzProsy = Proxy.getProxyClass(Collection.class
                .getClassLoader(), Collection.class);
        System.out.println(clazzProsy.getName());

        System.out.println("-----Begin constructor-----");
        //得到代理类上的构造函数
        Constructor[] constructors = clazzProsy.getConstructors();
        for (Constructor constructor : constructors) {
            String name = constructor.getName();
            // 单线程下StringBuilder效率比较高
            // 多线程时StringBuffer效率比较高
            StringBuilder strB = new StringBuilder(name);
            strB.append('(');
            Class[] clazzParams = constructor.getParameterTypes();
            for (Class clazzParam : clazzParams) {
                strB.append(clazzParam.getName()).append(',');
            }
            if (clazzParams.length != 0 && clazzParams != null)
                strB.deleteCharAt(strB.length() - 1);
            strB.append(')');
            System.out.println(strB.toString());
        }

        System.out.println("-----Begin methods-----");
        //得到代理类上的所有方法
        Method[] methods = clazzProsy.getMethods();
        for (Method method : methods) {
            String name = method.getName();
            // 单线程下StringBuilder效率比较高
            // 多线程时StringBuffer效率比较高
            StringBuilder strB = new StringBuilder(name);
            strB.append('(');
            Class[] clazzParams = method.getParameterTypes();
            for (Class clazzParam : clazzParams) {
                strB.append(clazzParam.getName()).append(',');
            }
            if (clazzParams.length != 0 && clazzParams != null)
                strB.deleteCharAt(strB.length() - 1);
            strB.append(')');
            System.out.println(strB.toString());
        }
        
        
    }
}


您需要登录后才可以回帖 登录 | 加入黑马