18_CGLib动态代理

【概述】

   已知JDK动态代理中的Proxy.newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)方法的第二个参数Class[] interfaces就是需要代理类实例实现的接口列表,即这里的代理类必须实现接口。

  CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,并顺势织入横切逻辑。采用CGLib可以为任何类创建织入横切代码的代理创建器。

 

【例子】(注意cglib-2.1.3版本,使用cglib-2.2会出错)

 

【Monitor.java】

package com.Higgin.demo;

/**
 * 监测类
 */
public class Monitor {
    public static void begin(){
        System.out.println("【操作数据库前】开始监测...");
    }
    
    public static void end(){
        System.out.println("【操作数据库后】结束检测,得到检测数据...");
    }
}

【PersonDap.java】

package com.Higgin.demo;

/**
 * 操作数据库的PersonDao类
 */
public class PersonDao {
    public void getAllPerson(){
        System.out.println("查询数据库得到所有的Person");
    }
    
    public void deleteAllPerson(){
        System.out.println("删除数据库所有的Person");
    }
}

 

 

【CglibProxy.java】

package com.Higgin.demo;

import java.lang.reflect.Method;

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

public class CglibProxy implements MethodInterceptor{

    private Enhancer enhancer=new Enhancer();
    public Object getProxy(Class clazz){
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    
    /**
     * intercept方法会拦截目标类所有方法的调用
     *    obj: 目标类的实例
     * method: 目标类方法的反射对象
     *   args: 方法的动态参数
     *  proxy: 代理类的实例
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {
        Monitor.begin();
        Object result=proxy.invokeSuper(obj, args);   //通过代理类调用父类中的方法
        Monitor.end();
        return result;
    }
    
}

【TestPersonDao.java】

package com.Higgin.demo;

public class TestPersonDao {
    public static void main(String[] args) {
        CglibProxy proxy=new CglibProxy();
        
        //可以通过getProxy(Class clazz)为一个目标类Proxy创建动态代理对象
        PersonDao personDao=(PersonDao) proxy.getProxy(PersonDao.class);
        
        personDao.getAllPerson();
     System.out.println("--------------------------------------")
     personDao.deleteAllPerson(); } }

 

【运行结果】

 

posted @ 2017-01-19 16:44  HigginCui  阅读(168)  评论(0编辑  收藏  举报