基于spring hibernate都使用了cglib,故今天也来学习下。
jdk动态代理主要是面向接口代理
而Cglib主要是针对类的代理
其实所有代理道理都是一样,通过代理对象去调用目标对象。
小例子来说明:
- package com.gosin.hibernate;
- 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 ClassTest {
- // 主方法测试aop的切入
- public static void main(String[] args) {
- Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(MyClass.class);
- enhancer.setCallback(new ClassInvokeImpl());
- MyClass my = (MyClass)enhancer.create();
- my.method();
- }
- // 为了实现切入我们写了一个内部类来实现业务逻辑方法主要是通过内部类实现了其中的
- // 一个接口MethodInterceptor来达到我们所要的业务逻辑方法
- public static class ClassInvokeImpl implements MethodInterceptor {
- // 这是实现其中接口所必须实现的方法,在方法体内我们来写
- // 入其中的业务逻辑
- public Object intercept(Object obj, Method method, Object[] arg,
- MethodProxy proxy) throws Throwable {
- //我们就简单的答应一些语句,具体业务逻辑我们还不考虑怎么写业务逻辑
- System.out.println("切入方法逻辑"+method);
- // 方法的回调实现业务逻辑
- proxy.invokeSuper(obj, arg);
- return null;
- }
- }
- }
- package com.gosin.hibernate;
- /*
- * 该demo是主要针对对类的方法的监听,实现aop的切入,一般来说
- * sun 公司提倡的是对接口的方法的切入,为了实现对类方法的切入,
- * 通过第三方的开发团队开发了cglib的jar包实现了对类的方法的监听(asm.jar需要调用)
- *
- * */
- public class MyClass {
- //下面考虑一下对类的方法的切入
- public void method(){
- System.out.println("MyClass method()!");
- }
- }
在来比较一下 BeanUtils 跟cglib
- public class A {
- private String username;
- private String password;
- private int age;
- private String sex;
- 省略 ……get/set方法
- }
- Class B 同 Class A 一样
- public class TestAB {
- public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {
- B b1 = new B();
- b1.setUsername("gosin");
- b1.setPassword("gosin");
- b1.setAge(24);
- b1.setSex("男");
- A a1 = new A();
- long begin = System.currentTimeMillis();
- for(int i=0;i<1000000;i++){
- BeanCopier bc = BeanCopier.create(B.class, A.class, false);
- bc.copy(b1, a1, null);
- }
- long end = System.currentTimeMillis();
- System.out.println("cglib-----"+(end-begin)+"-------");
- long begin1 = System.currentTimeMillis();
- for(int i=0;i<1000000;i++){
- BeanUtils.copyProperties(a1,b1);
- }
- long end1 = System.currentTimeMillis();
- System.out.println("BeanUtils-----"+(end1-begin1)+"-------");
- // System.out.println(a1.getAge());
- }
- }
运行结果 :
cglib-----1938-------
BeanUtils-----19250-------
两种实现 将近10倍的效率的差距 。。
由此可以看出cglib的强大。