JDK动态代理和CGlib动态代理
1.JDK动态代理
JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。
接口1 Man.java
//接口1
public interface Man {
public void work();
public void run();
}
接口2 Women.java
//接口1
public interface Man {
public void work();
public void run();
}
//接口2
public interface Women {
public void shopping();
}
实现接口类Person.java
//接口2
public interface Women {
public void shopping();
}
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();
}
运行结果
public class People implements Man, Women {
public void run() {
System.out.println("男人:兄弟快跑第二季");
}
public void work() {
System.out.println("男人:努力工作");
}
public void shopping() {
System.out.println("女人:打扮漂漂亮亮的");
}
}
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----------------");
}
}
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();
}
}
运行结果:
----上班之前打卡------
要去上班咯
----上班后打球去-------
|
我是菜鸟,我在路上。
2015年5月28日14:49:44