代理设计模式
代理设计模式:一个proxy代理,帮助我们去间接访问实现类里面的方法。
代理设计模式的分类:静态代理和动态代理(jdk动态代理、cglib动态代理)
静态代理的缺点:代理类需要我们自己去实现。
jdk的动态代理是利用了反射的原理生成代理类,根据接口生成的代理,所以需要接口才能使用
cglib动态代理是利用了asm框架来生成代理类,根据实现类生成的代理,所以可以不需要接口
(asm框架还可以将生成的类进行缓存,弥补生成类过程比较低效的缺点,但是执行效率高)
(jdk动态代理,因为应用反射所以执行效率较低,但是生成类的过程比较高效)
代理设计模式的优点:通过代理来控制实现类的访问,保证了程序的安全性
静态代理的实现(实现起来比较简单)
1、创建接口,依赖倒置原则,即面向接口编程
public interface SellCar {
public void sellCar();
}
2、创建实现类
/**
* 实现类
* @author 紫炎易霄
*/
public class CarMaster implements SellCar {
@Override
public void sellCar() {
System.out.println("我是车主,我要卖我的宝马车!");
}
}
3、创建代理类
/**
* 代理类
* @author 紫炎易霄
*/
public class CarProxy implements SellCar{
private CarMaster CarMaster;
/**
* 构造器初始化实现类
* @param carMaster
*/
public CarProxy(cn.zyyx.proxy.CarMaster carMaster) {
CarMaster = carMaster;
}
@Override
public void sellCar() {
System.out.println("前置通知:我是中介,我可以跟你推荐一辆二手宝马车!");
CarMaster.sellCar();
System.out.println("后置通知:谢谢,欢迎下次光临!");
}
}
4、创建调用类
public class CarBuyer {
/**
* 调用代理类的方法
* @param carProxy
*/
public void buyCar(CarProxy carProxy){
carProxy.sellCar();
}
}
5、测试类
public class Test {
public static void main(String[] args) {
CarBuyer carBuyer = new CarBuyer();
carBuyer.buyCar(new CarProxy(new CarMaster()));
}
}
运行结果
jdk动态代理
静态代理中的代理类我们不要,其余的保留。。。带着大家体验一下JDK替我们自动生成代理对象,然后调用方法。
1、实现回调对象(Proxy生成代理类时需要传入的对象)
/**
* 这个类传入到代理类中,会返回代理对象,从而调用invoke里面的方法
* 负责调用invoke方法
* @author 紫炎易霄
*/
public class Invocation implements InvocationHandler{
private Object target;
/**
* 实现类对象的初始化
* @param target
*/
public Invocation(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] objects) throws Throwable {
System.out.println("前置通知:我是中介,我可以跟你推荐一辆二手宝马车!");
Object invoke = method.invoke(target, objects);
System.out.println("后置通知:谢谢,欢迎下次光临!");
return invoke;
}
}
2、测试
public class Test {
public static void main(String[] args) {
//创建实现类对象
CarMaster carMaster = new CarMaster();
//代理类的调用程序对象
Invocation jdkCarProxy = new Invocation(carMaster);
//Jdk替我们自动生成代理对象
SellCar sellCar = (SellCar) Proxy.newProxyInstance(carMaster.getClass().getClassLoader(), carMaster.getClass().getInterfaces(), jdkCarProxy);
sellCar.sellCar();
}
}
运行结果与静态代理一模一样
cglib动态代理(需要cglib和asm的jar包)
1、引入jar包
2、创建回调对象
/**
* cglib动态代理的回调对象
* @author 紫炎易霄
*/
public class CglibCallback implements MethodInterceptor{
@Override
public Object intercept(Object obj, Method method, Object[] objs, MethodProxy methodProxy) throws Throwable {
System.out.println("前置通知:我是中介,我可以跟你推荐一辆二手宝马车!");
//调用目标类中的方法
Object invoke = methodProxy.invokeSuper(obj, objs);
System.out.println("后置通知:谢谢,欢迎下次光临!");
return invoke;
}
}
3、测试
public class Test {
public static void main(String[] args) {
//创建回调对象
CglibCallback cglibProxy = new CglibCallback();
//创建Enhancer对象
Enhancer enhancer = new Enhancer();
//设置目标类的class对象
enhancer.setSuperclass(CarMaster.class);
//设置回调对象
enhancer.setCallback(cglibProxy);
//创建代理对象
SellCar sellCar = (SellCar) enhancer.create();
//执行方法
sellCar.sellCar();
}
}
运行结果与静态代理和jdk动态代理一模一样