使用Cglib创建动态代理

由于JDK所提供的动态代理只能为接口创建动态代理,不能直接通过类来进行代理,所以这在没有定义接口的情况下是不实用的,这个时候就需要使用cglib来实现动态代理。

通过实例来看一下cglib的动态代理,其中只涉及到了3个类,一个是业务类,一个是cglib代理类,一个是测试类:


业务类StudentServiceImpl:

package cn.qing.cglib.proxy;

public class StudentServiceImpl {

	public String findStudent(String stuName) {
		System.out.println("findStudent method....");
		return "name:\t"+stuName;
	}

	public int findStudentNum() {
		System.out.println("findStudentNum method ...");
		return 20;
	}

}

cglib代理类:

package cn.qing.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;

public class CglibProxy implements MethodInterceptor {

	private Enhancer enhancer = new Enhancer();
	
	/**
	 * 使用Cglib返回一个代理对象
	 * @param clazz
	 * @return
	 */
	public Object getProxy(Class clazz)
	{
		//将需要代理的类设置为superclass
		enhancer.setSuperclass(clazz);
		//设置回调方法
		enhancer.setCallback(this);
		//创建一个代理
		return enhancer.create();
	}
	
	public Object intercept(Object object, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		
		System.out.println("befor execute method:"+method.getName());
		System.out.println("可以在这里添加一些前置操作....");
		
		//通过代理类调用父类中的方法
		Object obj = proxy.invokeSuper(object, args);
		
		System.out.println("after execute method:"+method.getName());
		System.out.println("可以在这里添加一些后置操作....");
		return obj;
	}

}

测试类:

package cn.qing.cglib.proxy;


public class TestCglibProxy {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		TestCglibProxy tcp = new TestCglibProxy();
		StudentServiceImpl service = tcp.getIStudentServiceInstance();
		System.out.println("getClass:"+service.getClass());
		System.out.println("super class:"+service.getClass().getSuperclass());
		
		System.out.println("*****************************");
		
		service.findStudent("xiaoming");
		
		System.out.println("*****************************");
		
		service.findStudentNum();

	}
	/**
	 * 通过cglib来获得实例代理对象
	 * @return
	 */
	public StudentServiceImpl getIStudentServiceInstance()
	{
		CglibProxy cp = new CglibProxy();
		StudentServiceImpl service = (StudentServiceImpl)cp.getProxy(StudentServiceImpl.class);
		return service;
	}

}

输出结果:

getClass:class cn.qing.cglib.proxy.StudentServiceImpl$$EnhancerByCGLIB$$1640169f
super class:class cn.qing.cglib.proxy.StudentServiceImpl
*****************************
befor execute method:findStudent
可以在这里添加一些前置操作....
findStudent method....
after execute method:findStudent
可以在这里添加一些后置操作....
*****************************
befor execute method:findStudentNum
可以在这里添加一些前置操作....
findStudentNum method ...
after execute method:findStudentNum
可以在这里添加一些后置操作....

由输出结果可以看出,第一个getclass()方法得到的确实是cglib创建的代理对象,通过调用getSuperclass()才获取到真正被代理的对象类,在方法执行的时候,也同样执行了在代理中添加的前置或后置代码。可以看到,cglib在创建代理的时候,直接使用了类,而并没有要求类实现接口,当然如果代理类实现了某些接口也是可以正常被代理的。而且cglib还提供了很多动态代理的功能点,这些是JDK动态代理所没有的。同时cglib也被使用在Spring框架中用来实现其AOP功能。

ps:在单独使用cglib时除了需要引入cglib包以外,还需要引入asm.jar包,因为cglib底层实现是通过ASM类实现的(ASM是小巧轻便的 Java 字节码操控框架 ,它能方便地生成和改造 Java 代码。)。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值