代理模式之cglib

我们在使用java自带的Proxy的时候,可以发现这样的操作只是适用于实现一些接口的类,但是我们可以cglib来躲避开实现接口这样的条件的限制,具体的操作如下,由于之前使用过hibernate3.2进行过一个开发,而hibernate也是一个实现cglib的操作的框架,那么我们在使用cglib的包的时候,可以到我们的hibernate3.2中把相应的jar包拷贝到我们要进行cglib测试的项目中去:

asm-attrs.jar

cglib-2.1.3.jar

asm.jar

cglib的实现实际上可以简单的这么的说就是一个把我们需要进行的代理操作的类,先创建出一个子类,在子类中进行一个父类的反射机制的操作,下面是一个实现引用cglib的项目:

新建一个java项目

,其中把开始涉及到的三个jar包拷贝到我们的java 项目中去,借助于buildpath,把其部署到我们的项目中去。

创建一个进行服务的类,userDaoImpl,

package com.fww.dao;

public class UserDaoImpl {
    public void add() {
        System.out.println("add");

    }
}

创建userDaoImpl的代理类:UserDaoProxy

package com.fww.proxy;

import java.lang.reflect.Method;

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

public class UserDaoProxy implements MethodInterceptor {
    private Object target;

    public Object getInstance(Object target) {
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        // 回调的方法
        enhancer.setCallback((Callback) this);
        // 创建一个代理的对象
        return enhancer.create();//通过字节码技术动态创建子类实例,
    }

    @Override
    public Object intercept(Object object, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        System.out.println("userdaoimpl操作开始");
        // proxy.invoke(object, args);
        Object result = proxy.invokeSuper(object, args);
        System.out.println("userdaoimpl的结束");
        return result;
    }
}

测试

 

通过以上的观察我们可以知道,我们的userdaoimpl是一个没有实现任何接口的类,其中我们进行上述代码的测试:

Test:

package com.fww.test;

import com.fww.dao.UserDaoImpl;
import com.fww.proxy.UserDaoProxy;

public class Test {
    public static void main(String[] args) {
        UserDaoProxy cglib = new UserDaoProxy();
        UserDaoImpl ud = (UserDaoImpl) cglib.getInstance(new UserDaoImpl());
        ud.add();
    }
}

个人理解:

  • cglib是一个巧妙的使用子类进行的一个操作,首先进行的是一个子类的创建,设置子类的父类是我们进行获取的服务类,然后进行的是回调的操作。其他的和java的Proxy就是一个基本的相似了。
  • 使用java的proxy的时候,可以观察: 获得创建新类的类名$Proxy,,,,但是使用的是cglib的时候是一个标识有事cglib生成的操作com.fww.dao.UserDaoImpl$$EnhancerByCGLIB$$f83dfcb2
  • cglib采用的是用创建一个继承实现类的子类,用asm库动态修改子类的代码来实现的,所以可以用传入的类引用执行代理类

你可能感兴趣的:(设计模式,cglib,代理模式)