java 代理(二)

上一编bolg我们已经了解了jdk实现的动态代理,接下来我们再来了解一下cglib的动态代理。

首先我们先看一下cglib动态代理怎么写。

目标类:BookService

package com.cglib.proxy;

public class BookService {

	public void add(){
		System.out.println("添加图书....");
	}
}

 Cglib代理实现类:BookCglibProxy

package com.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 BookCglibProxy implements MethodInterceptor {
	/** 被代理对象 */
	private Object target;
	
	public Object getInstance(Object target) {
		this.target = target;  
        Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(this.target.getClass());//目标类作为父类
        // 回调方法  
        enhancer.setCallback(this);  
        // 创建代理对象  
        return enhancer.create();  
	}
	
    /**
     * 回调方法
     */
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		System.out.println("事务开始....");  
        Object result = proxy.invokeSuper(obj, args);  
        System.out.println("事务结束....");  
        return result;  
	}

}

 Cglib测试类:TestCglibProxy

package com.cglib.proxy;

public class TestCglibProxy {

	public  static void main(String[] args) {
		BookService target = new BookService();
		BookCglibProxy bookCglib = new BookCglibProxy();
		BookService proxy = (BookService) bookCglib.getInstance(target);
		proxy.add();
	}
}

 测试结果

事务开始....
添加图书....
事务结束....

 接下来首先我们了解一下cglib实现动态代理的原理:cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

跟着我们简单了解一下CGLIB

 一、什么是CGLIB

CGLIB是一个强大的高性能的代码生成包。

      1>它广泛的被许多AOP的框架使用,例如:Spring AOP和dynaop,为他们提供方法的interception(拦截);

       2>hibernate使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的);

       3>EasyMock和jMock是通过使用模仿(moke)对象来测试java代码的包。

     它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。

二、底层

CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM(Java字节码操控框架),来转换字节码并生成新的类。除了CGLIB包,脚本语言例如 Groovy和BeanShell,也是使用ASM来生成java的字节码。当不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。所以cglib包要依赖于asm包,需要一起导入。下图为cglib与一些框架和语言的关系(CGLIB Library and ASM Bytecode Framework)
java 代理(二)
 

总结

典型的JDK动态代理创建过程可分为以下四个步骤:
1、通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(...);
2、通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{...});
3、通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4、通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入
Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
为了简化对象创建过程,Proxy类中的newInstance方法封装了2~4,只需两步即可完成代理对象的创建。
生成的ProxySubject继承Proxy类实现Subject接口,实现的Subject的方法实际调用处理器的invoke方法,而invoke方法利用反射调用的是被代理对象的的方法(Object result=method.invoke(proxied,args))

 

典型的CGLIB动态代理创建过程可分为以下两个步骤:

1、通过实现MethodInterceptor接口自定义方法创建代理对象;

     (1).方法内首先利用Enhancer对象设置需要代理的类;

     (2).然后设置回调方法enchancer.setCallback(this);

     (3).最后通过字节码技术动态创建代理对象enhancer.create()。

2、实现public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)回调方法拦截所有目标类方法的调用。

     (1).目标方法调用前的动态增强处理;

     (2).通过proxy代理实例调用proxy.invokeSuper(obj, args)调用父类方法执行目标方法;

     (3).目标方法调用后的动态增强处理。

 

 

你可能感兴趣的:(java)