本篇文章是通过看视频学习总结的内容, 如有错误的地方请谅解,并联系博主及时修改,谢谢您的阅读.
在生活中,其实也出现很多代理,比如卖/租房子的中介,送快递的小哥都属于一种代理,代理的本身其实就是代替某人去完成某件事情,被完成的事情实际上自己也能办到,只是没必要自己亲自去做,好比租房子的时候,可以直接去找房东租房,也可以去找房屋中介所,其实最终完成的事情就是租房这件事情。
静态代理,举个例子。老王的儿子年纪大了,该成家了,但是儿子却没有对象,不着急,new
一个就可以了!于是老王就征求到儿子的要求,开始为儿子寻找匹配儿子需求的对象。天下那么多单身汉,不可能老王一个人都能完成所有单身汉对象的代理,所以这里就被称为了静态代理。
根据老王为儿子寻找对象的案例中延申出了一种职业婚介所
,婚介所就能够同时代理很多人寻找对象的功能,不像老王一样只针对自己的儿子寻找对象,而是面向了整个社会,所以像这种可以灵活的代理,被称为动态代理。
以上全是自己个人的理解,如有错误的地方,看官请指正,谢谢啦。
BOOS直聘
和前程无忧
这些平台共同的特点都是为客户提供一份工作,那么可以新建一个接口 IPerson
,新增抽象方法 void mating();
public interface IPerson {
/** 找对象行为 **/
void mating();
}
Jack
开始为自己的儿子Tom
寻找对象public class Tom implements IPerson{
@Overried
public void mating(){
System.out.println("是个女的就行!");
}
}
Jack
为tom
寻找对象public class Jack implements IPerson{
private Tom tom;
public Jack(Tom tom){
this.tom = tom;
}
@Overried
public void mating(){
System.out.println("jack..开始给tom寻找对象");
System.out.println("jack..发现了不错的对象");
this.tom.mating();
System.out.println("tom和他的对象开始交往。。。");
}
}
// 测试客户端
public class ClientStaticProxy {
public static void main(String[] args) {
OldTom oldTom = new OldTom(new Tom());
oldTom.mating();
}
}
// 输出结果
// jack..开始给tom寻找对象
// jack..发现了不错的对象
// 是个女的就行!
// tom和他的对象开始交往。。。
JDK
动态代理Jdk
动态代理就好比婚介所,婚介所可以代理更多的人找对象,无论男女老,没有少,就比Jack
给儿子找对象灵活Tom
找对象的基础上增加一个mark
也找对象// 新增mark也开始找对象
public class Mark implements IPerson{
@Overried
public void mating(){
System.out.println("Mark: 年薪百万~");
}
}
JDK
动态代理来对tom
和mark
两个人进行代理// 使用jdk动态代理,需要实现InvocationHanlder中invoke方法
public class JdkProxy implements InvocationHanlder{
private IPerson target;
// 调用instance方法启动jdk动态代理
public IPerson getInstance(IPerson person){
this.target = person;
Class<? extends IPerson> clazz = this.target.getClass();
return (IPerson)Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
}
@Overried
public Object invoke(Object obj, Method method, Object[] objects){
System.out.println("开始为 '" + this.target.getClass().getSimpleName() + "'寻找对象..");
// this.target 是被代理的对象, objects是反射调用方法的形参
Object result = method.invoke(this.target, objects);
System.out.println("通过代理的方式成功寻找到了对象,开始交往...");
return result;
}
}
public class JdkProxyClient{
public static void main(String[] args){
// IPerson target = new Mark();
IPerson target = new Tom();
Tom tom = (Tom)new JdkProxy(target);
tom.mating();
}
}
// 输出结果,
// 开始为 'Tom' 寻找对象..
// Mark: 年薪百万~
// 通过代理的方式成功寻找到了对象,开始交往...
CGLIB
动态代理CGLIB
实现动态代理只需要修改Proxy
类,原有的IPerson
和Tom
,Mark
不做修改public class CglibProxy implements MethodInterceptor{
public Object instance(Class<?> clazz){
Enhancer enhancer = new Enhancer();
// 获取继承该类的所有类
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("开始为 '" + method.getDeclaringClass().getSimpleName() + "'寻找对象..");
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("通过代理的方式成功寻找到了对象,开始交往...");
return result;
}
}
public class CglibProxyClient{
public static void main(String[] args){
// IPerson target = new Mark();
IPerson target = new Tom();
Tom tom = (Tom)new JdkProxy(target);
tom.mating();
}
}
// 输出结果,
// 开始为 'Tom' 寻找对象..
// Mark: 年薪百万~
// 通过代理的方式成功寻找到了对象,开始交往...
Cglib
和 Jdk
动态代理, Cglib
在Spring
框架中使用的是最多的, 有兴趣可以看看源码.