一、什么是动态代理。
举个例子,当你需要找房子的时,你自己不想去找,而是通过中介帮你去找。这时你就是被代理者,而中介即使代理者
二 通过jdk实现动态代理
package com.ggg.proxy.jdk;
/**
* 目标接口
* @author ggg
*
*/
public interface Person {
void findHouse();
}
package com.ggg.proxy.jdk;
/**
* 被代理的目标对象
* @author ggg
*
*/
public class Zhangsan implements Person {
@Override
public void findHouse() {
//找房子的要求
System.out.println("找个三居室,两个卧室朝南的");
System.out.println("家电齐全");
}
}
package com.ggg.proxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/** * 代理对象 * @author ggg * */
public class AgentMan implements InvocationHandler {
private Person target;
public Object getInstance(Person target){
this.target = target;
Class clazz = target.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是中介,帮你找房子"); method.invoke(target, args);
System.out.println("请安心入住吧"); return null; }
}
package com.ggg.proxy.jdk;
/**
* 通过代理找到房子
* @author ggg
*
*/
public class Main {
public static void main(String[] args) {
Person obj = (Person)new AgentMan().getInstance(new Zhangsan());
System.out.println("生成的代理对象是:"+ obj.getClass());
obj.findHouse();
}
}
三、手写jdk的动态代理实现上述功能
四、CGLib的动态代理
https://blog.csdn.net/danchu/article/details/70238002
http://www.iteye.com/topic/799827
https://blog.csdn.net/luanlouis/article/details/24589193
package com.ggg.proxy.cglib;
/**
* 被代理对象
* @author ggg
*
*/
public class Zhangsan {
public void findHouse(){
System.out.println("三居室,两个卧室朝南");
}
}
package com.ggg.proxy.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 ggg
*
*/
public class AgentMan implements MethodInterceptor{
public Object getInstance(Object obj) throws Exception{
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("我是中介,帮你找房子");
proxy.invokeSuper(obj, args);//这个地方千万不能写成proxy.invoke() 会死循环
System.out.println("请安心入住吧");
return null;
}
}
public Object getInstance(Object obj) throws Exception{
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("我是中介,帮你找房子");
proxy.invokeSuper(obj, args);//这个地方千万不能写成proxy.invoke() 会死循环
System.out.println("请安心入住吧");
return null;
}
}
package com.ggg.proxy.cglib;
/**
* 通过代理找到房子
* @author ggg
*
*/
public class Main {
public static void main(String[] args) {
try {
Zhangsan zhangsan = (Zhangsan) new AgentMan().getInstance(new Zhangsan());
zhangsan.findHouse();
} catch (Exception e) {
e.printStackTrace();
}
}
}
五、jdk的动态代理与CGLib动态代理的区别
1.JDK的动态代理是通过接口来进行强制转换,生成后的代理对象,可以强制转换为接口
2.CGLib的动态代理是通过生成一个被代理对象的子类,然后重写父类的方法
生成以后的对象,可以强制转换成被代理的对象