JDK动态代理和CGlib动态代理
1.JDK动态代理
JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。
接口1 Man.java
//接口1
public interface Man {
public void work();
public void run();
}
接口2 Women.java
//接口2
public interface Women {
public void shopping();
}
实现接口类Person.java
public class People implements Man, Women {
public void run() {
System.out.println("男人:兄弟快跑第二季");
}
public void work() {
System.out.println("男人:努力工作");
}
public void shopping() {
System.out.println("女人:打扮漂漂亮亮的");
}
}
代理类 DynamicProxy.java
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxy implements InvocationHandler { // 需要被代理类的引用 private Object object; // 构造方法 public DynamicProxy(Object object) { this.object = object; } public Object getProxy() { //通过Proxy类的newProxyInstance方法动态生成一个动态代理,并返回它 //java还让这个动态生成的$Proxy0类实现了要代理类的实现的所有接口,并继承了Proxy接口。 //得到的其实是一个类名叫$Proxy0 extends Proxy implements ***Interface的类 return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this); } //重写invoke方法,这里处理真正的方法调用 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { beforeDoing(); Object invoke=method.invoke(object, args); afterDoing(); return invoke; } public void beforeDoing(){ System.out.println("-------------before---------------"); } public void afterDoing(){ System.out.println("-------------after----------------"); } }
测试类 Test.java
public static void main(String[] args) { People realSubject=new People(); DynamicProxy dynamicProxy=new DynamicProxy(realSubject); Man man=(Man) dynamicProxy.getProxy(); man.work(); man.run(); Women women=(Women)dynamicProxy.getProxy(); women.shopping(); }
运行结果
-------------before--------------- 男人:努力工作 -------------after---------------- -------------before--------------- 男人:兄弟快跑第二季 -------------after---------------- -------------before--------------- 女人:打扮漂漂亮亮的 -------------after---------------- |
2.CGlib动态代理
CGLIB是一个强大的高性能的代码生成包。它广泛的被许多AOP的框架使用,例如Spring
AOP和dynaop,为他们提供方法的interception(拦截)。最流行的OR Mapping工具hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的)。EasyMock和jMock是通过使用模仿(mock)对象来测试java代码的包。它们都通过使用CGLIB来为那些没有接口的类创建模仿(mock)对象。
实现类 Man.java
public class Man { public void work(){ System.out.println("要去上班咯"); } }
代理类Cglib.java
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 Cglib 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("----上班之前打卡------"); proxy.invokeSuper(obj, args); System.out.println("----上班后打球去-------"); return null; } }
测试类Test.java
public class Test { public static void main(String[] args) { // 代理类 Cglib cglib = new Cglib(); // 实现类 Man impl = (Man) cglib.getInstance(new Man()); impl.work(); } }
运行结果:
----上班之前打卡------ 要去上班咯 ----上班后打球去------- |
参考博客: http://blog.csdn.net/hintcnuie/article/details/10954631
http://www.iteye.com/topic/683613/
我是菜鸟,我在路上。
2015年5月28日14:49:44
时间: 2024-08-27 22:20:48