最简单的是静态代理方法,即代理模式,这里就不多啰嗦了。。
重点说一下JDK的动态代理和Cglib的动态代理吧
先说JDK的,需要被代理的类需要有接口,否则无法实现
package proxy.dynamic;
public interface IBook {
void add();
}
实现接口的类如下
package proxy.dynamic;
public class Book implements IBook {
@Override
public void add() {
System.out.println("Add Method!");
}
}
创建一个代理类,需要实现一个接口InvocationHandler接口,里面有一个invoke方法需要实现
同时创建一个生成实例的方法
package proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class BookProxy implements InvocationHandler{
private Object target;
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);//这里需要接口
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result=null;
System.out.println("Before");
result=method.invoke(target, args);//执行方法
System.out.println("After");
return result;
}
}
接下来创建测试类
package proxy.dynamic;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
BookProxy bp = new BookProxy();
IBook book = (IBook) bp.bind(new Book());
book.add();
}
}
可以看到依次输出了Before,方法,After
下面说一下Cglib的代理,Cglib代理不需要原类实现接口,依赖Cglib和asm两个Jar包
需要代理的类如下
package cglib.proxy;
public class Book {
public void add() {
System.out.println("Add Method!");
}
}
创建一个代理类,实现MethodInterceptor接口,同时写一个生成实例的getInstance方法
package 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 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();
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("Before");
proxy.invokeSuper(obj, args);
System.out.println("After");
return null;
}
}
接下来就是简单测试一下
package cglib.proxy;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
Book book=(Book) proxy.getInstance(new Book());
book.add();
}
}
运行效果一样的
简单总结一下,JDK动态代理,需要实现一个接口InvocationHandler,要求被代理的对象必须有一个接口
Cglib代理需要实现MethodInterceptor接口,不需要被代理的类必须有接口
性能方法,参考其他文章,说JDK代理适合多例模式,而单例模式Cglib更好一些,因为Cglib是用底层的字节码技术生成实例,耗费时间较长,性能不如JDK动态代理。(有待验证。。)
来源:oschina
链接:https://my.oschina.net/u/2247881/blog/523352