说到代理,就必须要说静态代理和动态代理。
代理其实本身就容易理解,就是说一个中间商人,我从厂商拿货比如说面膜,你找我买的这么一个存在,而这个原理在java中有什么用呢?
简单说,在java中我们知道一个类做一件事情,所以这里的厂商有面膜可以卖,这个事情他是一个整体,对吧,所以厂商的功能就是可以出售面膜。那一开始你直接找厂商买面膜,没有问题,用的很舒服,皮肤也变好了,突然有一天你发现自己有一条眼角纹了,你就想整点眼霜用用,但是呢又不想再去找别的厂商去试哪款适合自己。这个时候你就找到我了,我说我可以同时给你买到眼霜和面膜,那以后你就从我这里买了。我在原先卖面膜的厂商那里买到面膜,在从其他地方买到眼霜,这样子就刚好适合你的需求了。如果你以后还需要眼影啥的,还可以继续找我,对不对。
所以,这个例子在java中应该怎么实现呢,首先厂商类;
public class MianMoServiceImpl implements SaleServers {
@Override
public void sale(String s) {
System.out.println(s+"面膜");
}
}
接口
public interface SaleServers {
void sale(String s);
}
代理类
public class InvocationHandlerImpl implements InvocationHandler {
// 真实业务对象
private Object target;
public InvocationHandlerImpl(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("买了眼霜");
Object invoke = method.invoke(target, args);
System.out.println("买了眼影");
return invoke;
}
}
消费者实现
public static void main(String[] args) throws Exception {
//开始只能买面膜
MianMoServiceImpl m=new MianMoServiceImpl();
m.sale("不走代理");
//可以购买眼霜等
// 生成代理类的class对象
Class<?> clazz = Proxy.getProxyClass(m.getClass().getClassLoader(), m
.getClass().getInterfaces());
// 创建InvocationHandler
InvocationHandler myInvocationHandler = new InvocationHandlerImpl(m);
// 获取代理类的构造器对象
Constructor constructor = clazz.getConstructor(new Class[] {InvocationHandler.class});
// 反射创建代理对象
SaleServers proxy = (SaleServers)constructor.newInstance(myInvocationHandler);
proxy.sale("走代理");
}
结果
最后说下JDK代理和Cgliber代理的区别;
JDK代理在最后可以看到拿到的对象还是SaleServers来接收的,这就要求被代理对象和最后的代理对象要实现同一个接口。
而Cgliber代理采用的是字节码技术,直接在代理过程中生成一个被代理对象,所以不需要实现相同接口。
就相当于如果上面用cgliber代理的话,最后就不用SaleServers 来接收对象。可以直接试用MianMoServiceImpl来接收。
总结:
不论是动态代理还是静态代理,还是或JDK代理或者cgliber代理,最后的作用都是对被代理类进行一个增强的作用(在不改变原有代码的基础上),其很好的实现了开闭原则,然后,AOP相当于是对代理进行了一个封装,我们现在只需要加一个注解就可以很好的实现功能增强(环绕,前置,后置等等),AOP虽然好用,但是我们还是需要了解其内部的一些实现原理的。