先讲一下概念,代理,什么是代理?
举个例子吧。很多人喜欢在淘宝或者天猫上淘一些生活用品或者衣服,这个购买过程就产生了本文的重点,代理。你知道你购买的商家叫什么名,但是不知道他后面的厂家是谁?这件衣服是哪个厂家卖给了你,你完全不知道,其实这个过程就是代理,厂家委托商家卖衣服给你,商家就是代理类,代理卖这个厂家这个品牌的衣服,厂家就是委托类,委托商家埋衣服。什么北京区代理,黑龙江总代理,都是这个方式的。
代理分为动态,和静态。先说说静态代理,
//代理接口类
public interface SpiderOrder {
//订单1
public void crawlingSpider1();
//订单2
public void crawlingSpider();
}
//委托类
public class SpiderOrderImpl implements SpiderOrder{
@Override
public void crawlingSpider1() {
// TODO Auto-generated method stub
System.out.println("订单1-----");
}
@Override
public void crawlingSpider() {
// TODO Auto-generated method stub
System.out.println("订单2-----");
}
}
//静态代理类
public class SpiderOrderProxy implements SpiderOrder{
private SpiderOrderImpl spiderOrderImpl;
public SpiderOrderProxy(SpiderOrderImpl spiderOrderImpl) {
super();
this.spiderOrderImpl = spiderOrderImpl;
}
@Override
public void crawlingSpider1() {
// TODO Auto-generated method stub
spiderOrderImpl.crawlingSpider1();
System.out.println("具体的执行");
}
@Override
public void crawlingSpider() {
// TODO Auto-generated method stub
spiderOrderImpl.crawlingSpider();
System.out.println("具体的执行");
}
}
说明:你看这个静态代理有啥缺点吗? 代理接口新增一个方法,实现类要全都实现,静态代理类也要全部都实现这个新增方法。你这接口方法少还行,项目大了,经常会变动的。还有就是这个你知道哪个类是代理类,可以直接去用,事先是知道的。如果不知道呢具体的代理类,如何呢?接下来讲解动态代理类。
动态代理,利用了很多反射的技术知识,开始
//中介类
public class WorkInvocationHandler implements InvocationHandler{
private Object object;//代理类持有一个委托类对象
public WorkInvocationHandler(Object object) {
super();
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(" 方法调用之前 ");
method.invoke(object, args);
System.out.println(" 方法调用之后 ");
return null;
}
}
中介类必须实现InvoCationhandler类,来处理。当我们调用代理的具体的方法的时候,会统一的到中介类的invoke方法上,这样我们可以在invoke方法上做具体的逻辑,根据不同的情况做不同的处理,参数Method是方法,proxy是具体的代理类。这个中介类的输出是在这个代理类具体实现方法前,和方法后做具体的处理。
public class InvokeClient {
public static void main(String[] args) {
SpiderOrder spidOrder = new SpiderOrderImpl();
InvocationHandler invocation = new WorkInvocationHandler(spidOrder);
SpiderOrder proxySipderOrder = (SpiderOrder) Proxy.newProxyInstance(invocation.getClass().getClassLoader(), spidOrder.getClass().getInterfaces(), invocation);
System.out.println("输出这个反射出来的proxySipderOrder" + proxySipderOrder.getClass().getName());
//这实际上回调用到
proxySipderOrder.crawlingSpider();
proxySipderOrder.crawlingSpider1();
}
}
会发现,中介类与代理类也构成了一个静态代理关系,这个关系中,中介类是委托类,代理类是代理类。这样做的好处就是将代理类与被代理对象分离开来,这样我们可以在代理类与被代理类随意组合。也就是说动态代理是由两组静态代理构成的,这也基本是原理了。自己品味一下这个JDK动态代理。
spring AOP是基本原理是动态代理,分为jdk的动态代理,和CGLIB代理组成。