`
jameswxx
  • 浏览: 772285 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java动态代理之cglib

    博客分类:
  • java
阅读更多

        cglib是一个强大的高性能的代码生成包,他广泛的被许多的AOP框架使用,例如Spring AOP 和dynaop ,为他们提供方法的拦截(interception),最流行的OR Mapping 工具hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联。在这里要说明的是,jdk提供了动态代理功能,但是被代理类必须要有接口,否则是生成不了代理的,但是cglib生成代理时,不需要目标类有接口,因为它借助了asm直接修改class文件的字节码。

     

      就这个动态代理说开来,其实spring的aop不是什么神秘的东西,就是借助动态代理来实现的,并且spring内置了两种代理生成方式,一个就是jdk动态代理API,一个就是cglib。典型的spring组件如声明式的事务管理,通知等。spring的IOC更简单,根据配置文件反射而已。这些东西自己实现并不是什么难事,但是要做到spring那样完善和庞大就是另外一回事了。spring提供的测试框架的mock模块当然也是利用了动态代理的。

下面看看demo吧,具体可自行查阅cglib文档
①:创建一个简单的类,注意该类不能声明为final

QueryDAO.java

package com.cglib.proxy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @version 1.0
 * @history
 */
public class QueryDAO {

   
    @SuppressWarnings("unchecked")
    public List executeQuery(String userName) throws Exception{
        List list = this.queryForList(userName);
        return list;
    }
   
   
    @SuppressWarnings({ "unchecked", "static-access" })
    public List queryForList(String userName){
        try {
            Thread.currentThread().sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Map<String,String> paramMap = new HashMap<String, String>();
        paramMap.put("userName", userName);
        List list = new ArrayList();
        list.add(paramMap);
        return list;
    }
}


②:创建性能检测类PerformanceMonitor,需要实现MethodInterceptor(方法拦截)
PerformanceMonitor.java

package com.cglib.proxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * @version 1.0
 * @history
 */
public class PerformanceMonitor implements MethodInterceptor {

    private Object target;
    private Enhancer enhander = new Enhancer();

    public Object createProxy(Object target){
        this.target = target;
        enhander.setSuperclass(target.getClass()); //指定父类
        enhander.setCallback(this); //回调当前类
        return enhander.create(); //创建代理类实例
    }


    public Object intercept(Object arg0, Method method, Object[] param,
            MethodProxy proxyMethod) throws Throwable {
        long startTime = System.currentTimeMillis(); //开始时间
        Object result = method.invoke(this.target, param);  //反射回调方法
        long endTime = System.currentTimeMillis(); //结束时间
        System.out.println("执行该方法所需时间:" + (endTime-startTime)+"毫秒" );
        return result;
    }

}


③:Cglib代理类测试效果:
CglibProxyTest.java

package com.cglib.proxy;

public class CglibProxyTest {

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        QueryDAO target = new QueryDAO(); //声明被代理类
        PerformanceMonitor performance = new PerformanceMonitor();
        QueryDAO dao = (QueryDAO)performance.createProxy(target);
        dao.executeQuery("admin");
    }

}


输入结果
执行该方法所需时间:187毫秒

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics