代理模式
A买房,B卖房
1,A找到B买房,B呢只知道自己要卖100万,其它流程一概不知。
2,引入代理,A找到代理C,代理C知道买房买房的流程,这时候代理C会找卖家B签合同,走各种流程,所以买家A只需要和中介C对接就可以了。
总结:相当于通过中介C这个对象,我们完成了一些B不懂的东西,最终帮买家完成了买房这个事情。
代理方式 | 特点 |
JDK | 需要抽象出接口 |
Cglib | 字节码操作 |
JDK
先抽象出买房的接口类
public interface ByHouse {
void buyProcess(String param);
}
然后实现此接口,并做具体的实现方法
public class ByHouseImpl implements ByHouse {
@Override
public void buyProcess(String param) {
System.out.println("sign " + param);
}
}
创建代理类,并增强ByHouse方法。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class BuyHouseProxy implements InvocationHandler {
private ByHouse byHouse;
public BuyHouseProxy(ByHouse byHouse) {
this.byHouse = byHouse;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("-----------prepare money-------------");
Object invoke = method.invoke(byHouse, args);
System.out.println("-----------move in the new House-------------");
return invoke;
}
}
通过代理实现买房测试
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
ByHouse byHouse = new ByHouseImpl();
InvocationHandler byHouseProxy = new BuyHouseProxy(byHouse);
ByHouse proxyInstance = (ByHouse) Proxy.newProxyInstance(
byHouseProxy.getClass().getClassLoader(),//代理类的类加载器
byHouse.getClass().getInterfaces(),//被代理类的接口,如果有多个,就是数组形式传入
byHouseProxy);//代理类实例
proxyInstance.buyProcess("合同");
}
}
输出:
-----------prepare money-------------
sign 合同
-----------move in the new House-------------
由此实现了对买房流程的增强
CGLIB
创建买房类
public class CGBuyHouse {
public void process(){
System.out.println("签合同");
}
}
创建买房拦截器,并对买房方法进行增强。
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 ByHouseInterceptor implements MethodInterceptor{
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("------prepare money -----");
Object o1 = methodProxy.invokeSuper(o, objects);
System.out.println("------move in new house-----");
return o1;
}
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(CGBuyHouse.class);
enhancer.setCallback(new ByHouseInterceptor());
CGBuyHouse cGsubject = (CGBuyHouse) enhancer.create();
cGsubject.process();
}
}
输出 :
------prepare money -----
签合同
------move in new house-----
为什么使用CGLIB
CGLIB代理主要通过对字节码的操作,为对象引入间接级别,以控制对象的访问。我们知道Java中有一个动态代理也是做这个事情的,那我们为什么不直接使用Java动态代理,而要使用CGLIB呢?答案是CGLIB相比于JDK动态代理更加强大,JDK动态代理虽然简单易用,但是其有一个致命缺陷是,只能对接口进行代理。如果要代理的类为一个普通类、没有接口,那么Java动态代理就没法使用了