代理分为静态代理和动态代理
按照代理创建的时期,可以分为静态代理和动态代理:
(1) 静态代理:由程序员或者自动生成工具生成代理类,然后进行代理类的编译和运行。在代理类、委托类运行之前,代理类已经以.class的格式存在。
(2)动态代理:在程序运行时,由反射机制动态创建而成。
(3)JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
代理方式实现优点缺点特点
JDK静态代理代理类与委托类实现同一接口,并且在代理类中需要硬编码接口实现简单,容易理解代理类需要硬编码接口,在实际应用中可能会导致重复编码,浪费存储空间并且效率很低好像没啥特点
JDK动态代理代理类与委托类实现同一接口,主要是通过代理类实现InvocationHandler并重写invoke方法来进行动态代理的,在invoke方法中将对方法进行增强处理不需要硬编码接口,代码复用率高只能够代理实现了接口的委托类底层使用反射机制进行方法的调用
CGLIB动态代理代理类将委托类作为自己的父类并为其中的非final委托方法创建两个方法,一个是与委托方法签名相同的方法,它在方法中会通过super调用委托方法;另一个是代理类独有的方法。在代理方法中,它会判断是否存在实现了MethodInterceptor接口的对象,若存在则将调用intercept方法对委托方法进行代理可以在运行时对类或者是接口进行增强操作,且委托类无需实现接口不能对final类以及final方法进行代理底层将方法全部存入一个数组中,通过数组索引直接进行方法调用
JDK动态代理
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author chexingyou
* @date 2013-6-6
*/
interface Dao {
void show();
void say();
}
interface Dao2 {
void say();
}
class Imp implements Dao, Dao2 {
public void show() {
System.out.println("do show");
}
public void say() {
System.out.println("do say");
}
}
class Handler implements InvocationHandler {
private Object obj;
public Handler(Object obj) {
this.obj = obj;
}
public static Object create(Object obj) {
return Proxy.newProxyInstance(Imp.class.getClassLoader(), Imp.class.getInterfaces(),
new Handler(obj));
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before " + method.getName());
Object ret = method.invoke(obj, args);
System.out.println("after " + method.getName());
return ret;
}
}
public class Test {
public static void main(String[] args) {
Dao imp = new Imp();
Dao proxy = (Dao) Handler.create(imp);
proxy.show();
proxy.say();
Dao2 proxy2 = (Dao2) Handler.create(imp);
proxy2.say();
}
}
package cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* @author chexingyou
* @date 2013-6-7
*/
class Imp {
public void say() {
System.out.println("say()");
}
}
class CglibProxy implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
throws Throwable {
System.out.println("do before");
Object ret = proxy.invokeSuper(obj, args);
System.out.println("do after");
return ret;
}
public Object getProxy(Class> clazz) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
}
public class Test {
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
Imp imp = (Imp) proxy.getProxy(Imp.class);
imp.say();
}
}