cglib动态代理的实现

1.cglib介绍(摘抄自官网):

Byte Code Generation Library is high level API to generate and transform JAVA byte code.It is used by AOP, testing, data access frameworks to generate dynamic proxy objects and intercept field access。

2.cglib原理:

cglib底层使用字节码处理框架ASM,来转换字节码并生成新的类。执行过程中动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。

3.常用API

加入依赖:

<dependency>
  <groupId>cglib</groupId>
  <artifactId>cglib</artifactId>
  <version>3.2.4</version>
</dependency>

测试服务类:

package com.lojzes.cglib;

/**
 * 备注:
 */
public class StudentService {
    public void add(String name) {
        System.out.println("add --->>>" + name);
    }

    public int del(int id) {
        System.out.println("del --->>>" + id);
        return 0;
    }

    public String get(int id) {
        System.out.println("get --->>>" + id);
        return "hello";
    }

}

Callback:

package com.lojzes.cglib;

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

import java.lang.reflect.Method;

/**
 * 备注:cglib 对方法的拦截
 */
public class StudentServiceCallback implements MethodInterceptor {

    /**
     * 备注: obj:被增强后的对象
     *  method:被拦截的方法
     *  proxy:被拦截方法的代理
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("方法执行之前--->>>");
        Object invoke = proxy.invokeSuper(obj, args);
        System.out.println("方法执行之后--->>>");
        return  invoke;
    }
}

测试类:

package com.lojzes;

import com.lojzes.cglib.StudentService;
import com.lojzes.cglib.StudentServiceCallback;
import net.sf.cglib.proxy.*;
import org.junit.Test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 备注:
 */
public class CglibTest {

    /**
    * 备注: 动态代理生成并调用
    */
    @Test
    public void test01(){
        //cglib增强器
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(StudentService.class);
        //设置回调
        enhancer.setCallback(new StudentServiceCallback());
        //生成代理
        StudentService studentService= (StudentService) enhancer.create();
       studentService.add("lojzes");
    }
    /**
    * 备注: 接口生成器
    */
    @Test
    public void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        InterfaceMaker interfaceMaker = new InterfaceMaker();
        interfaceMaker.add(StudentService.class);
        Class newInterfaceClz = interfaceMaker.create();
        Method[] methods = newInterfaceClz.getMethods();
        for (Method method : methods) {
            System.out.println("新接口的方法名称:--->>>"+method.getName());
        }

        //创建代理类
        Object o = Enhancer.create(Object.class, new Class[]{newInterfaceClz},new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                //以下是新接口中方法的实现
                if(method.getName().equals("add")){
                    System.out.println("add...");
                    return Void.TYPE;
                }
                if(method.getName().equals("del")){
                    System.out.println("del...");
                    return 1;
                }
                if(method.getName().equals("get")){
                    System.out.println("get...");
                    return "haha";
                }
                return "default";
            }
        });
        //调用方法
        Method del = o.getClass().getDeclaredMethod("del", new Class[]{int.class});
        Object delR = del.invoke(o, new Object[]{1024});
        System.out.println("del 返回--->>>"+delR);

        Method add = o.getClass().getDeclaredMethod("add", new Class[]{String.class});
        Object addR = add.invoke(o, new Object[]{"dodo"});
        System.out.println("add 返回--->>>"+addR);

        Method get = o.getClass().getDeclaredMethod("get", new Class[]{int.class});
        Object getR = get.invoke(o, new Object[]{123});
        System.out.println("get 返回--->>>"+getR);
    }
}

猜你喜欢

转载自blog.csdn.net/lyitit/article/details/80806605