AOP之署理模式(三)

AOP之代理模式(三)

    JDK自从1.3版本开始,就引入了动态代理,JDK的动态代理用起来非常简单,但是它有一个限制,就是使用动态代理的对象必须实现一个或多个接口 。如果想代理没有实现接口的类可以使用CGLIB包。先来看看GCLIB的具体使用,然后再对应代码深入理解。

 

    在使用CGLIB时需引入cglib-nodep-2.1_3.jar包。

    先来一个基础类,注意,这里没有对应的接口。

public class GreetingImpl {

	public void sayHello(String name) {
		System.out.println("Hello! " + name);
	}
}

    然后就是咱们定义的动态代理类

package com.tgb.sld.cglibproxy;

import java.lang.reflect.Method;

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

/**
 * CGLib动态代理类
 *
 * @author sunliduan 2015年5月26日 下午3:32:38
 */
public class CGLibDynamicProxy implements MethodInterceptor {

	// 定义被代理的对象
	private Object target;

	// 根据被代理对象,创建代理类
	public Object createProxy(Object target) {
		this.target = target;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.target.getClass());// 设置代理目标
		enhancer.setCallback(this);// 设置回调
		enhancer.setClassLoader(target.getClass().getClassLoader());
		return enhancer.create();
	}

	// 通过代理类调用被代理类的方法或者特殊处理(如切入方法)
	@Override
	 public Object intercept(Object proxy, Method method, Object[] params,
	            MethodProxy methodProxy) throws Throwable {
		before();
		Object object= methodProxy.invoke(target, params);
		after();
		return object;
	}

	private void before() {
		System.out.println("Before==通过CGLib动态代理把我加到被切方法之前");
	}

	private void after() {
		System.out.println("After==通过CGLib动态代理把我加到被切方法之后");
	}

}

    其实在代理类中和JDK动态代理实现的功能或者是原理来说,是很类似的:首先定义一个Object类型的被代理对象;然后根据被代理对象,创建代理类;最后通过代理类调用被代理类的方法或者特殊处理(如切入方法)。

 

    客户端的调用代码如下:

<span style="font-size:18px;">package com.tgb.sld.cglibproxy;

public class Client {

	public static void main(String[] args) {

		CGLibDynamicProxy cgLibDynamicProxy=new CGLibDynamicProxy();
		GreetingImpl greetingImpl= (GreetingImpl) cgLibDynamicProxy.createProxy(new GreetingImpl());
		
		greetingImpl.sayHello("duanduan");
		
	}

}</span>


    这样,我们基本上解决了JDK动态代理的局限-不能代理没有对应接口的类。CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。当然这些实际的功能是asm所提供的,asm又是什么?Java字节码操控框架,具体是什么大家可以上网查一查,cglib就是封装了asm,简化了asm的操作,实现了在运行期动态生成新的class。


    这样算是完美了,当然不是的,不知道大家有没有注意,在我们每个代理类中,我们都需要重新写一篇切入的方法,这样显然不能实现很好的复用。为了解决这个问题,我们又该如何完善呢?