局域网网站制作教程,广州番禺区核酸检测点,浅蓝色.net企业网站源码带后台,wordpress 插件 安装教程代理模式
代理模式是常用的java设计模式#xff0c;他的特征是代理类与委托类有同样的接口#xff0c;代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类#xff0c;以及事后处理消息等。代理类与委托类之间通常会存在关联关系#xff0c;一个代理类的对象…代理模式
代理模式是常用的java设计模式他的特征是代理类与委托类有同样的接口代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类以及事后处理消息等。代理类与委托类之间通常会存在关联关系一个代理类的对象与一个委托类的对象关联代理类的对象本身并不真正实现服务而是通过调用委托类的对象的相关方法来提供特定的服务。简单的说就是我们在访问实际对象时是通过代理对象来访问的代理模式就是在访问实际对象时引入一定程度的间接性因为这种间接性可以附加多种用途。
代理模式的目的
1.功能增强通过代理业务对原有业务进行增强
2.控制访问通过代理对象的方式间接的访问目标对象防止直接访问目标对象给系统带来不必要的复杂性
静态代理
简单来说代理模式就是将被代理类包装起来然后重新实现相同的方法并且调用原来方法的同时可以在方法前后添加一个新的处理。而这种包装可以使用继承或者组合来使用。当我们调用的时候需要使用的是代理类的对象来调用而不是原来的被代理对象。
静态代理的特点 1.代理类是手动实现的需要自己去创建一个类 2.代理类所代理的目标类是固定的 静态代理可以通过继承或实现代理类的接口来实现
通过继承实现静态代理
通过继承被代理对象重写被代理方法可以对其进行代理。优点被代理类无需实现接口缺点只能代理这个类要想代理其他类要想代理其他类需要写新的代理方法。cglib动态代理就是采用这种方式对类进行代理。不过类是由cglib帮我们在内存中动态生成的。
public class Tank{public void move() {System.out.println(Tank moving cla....);}public static void main(String[] args) {new ProxyTank().move();}
}
class ProxyTank extends Tank{Overridepublic void move() {System.out.println(方法执行前...);super.move();System.out.println(方法执行后...);}
}通过组合实现静态代理
定义一个被代理类需要和代理类都需要实现的接口。(接口在这里的目的就是起一个规范作用保证被代理类和代理类都实现了接口中的方法)。代理类需要将该接口作为属性实例化时需要传入该接口的对象这样该代理类就可以实现代理所有实现这个接口的类了。优点可以代理所有实现接口的类。缺点被代理的类必须实现接口。JDK动态代理就是采用的这种方式实现的。同样的代理类是由JDK自动帮我们在内存生成的。
静态代理存在的问题
1.当目标类增多时代理类也需要增多导致代理类的关系不便
2.当接口当中的功能增多或者修改都会影响实体类违反开闭原则程序对访问开放对修改关闭
动态代理
动态代理其实本质还是 将被代理类包装一层生成一个具有新的相同功能的代理类。 但是与静态代理不同的是这个代理类我们自己定义的。而动态代理这个代理类是根据我们的提示动态生成的。
相比于静态代理动态代理的优势在于可以很方便的对代理类的函数进行统一的处理而不用修改每个代理类中的方法。
实现动态代理的方式
1.JDK动态代理
2.CGLIB动态代理
JDK动态代理
通过java提供的Proxy类帮我们创建代理对象。优点可以生成所有实现接口的代理对象缺点JDK反射生成代理必须面向接口, 这是由Proxy的内部实现决定的。生成代理的方法中你必须指定实现类的接口它根据这个接口来实现代理类生成的所实现的接口。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*** 使用jdk的动态代理*/
public class Tank implements Movable{Overridepublic void move() {System.out.println(Tank moving cla....);}public static void main(String[] args) {Tank tank new Tank();// reflection 反射 通过二进制字节码分析类的属性和方法//newProxyInstance: 创建代理对象// 参数一: 被代理类对象// 参数二接口类对象 被代理对象所实现的接口// 参数三调用处理器。 被调用对象的那个方法被调用后该如何处理Movable o (Movable)Proxy.newProxyInstance(Tank.class.getClassLoader(),new Class[]{Movable.class},new LogProxy(tank));o.move();}
}class LogProxy implements InvocationHandler {private Movable movable;public LogProxy(Movable movable) {this.movable movable;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(方法:method.getName()()执行前);Object invoke method.invoke(movable, args); // 此处相当于 movable.move()System.out.println(方法:method.getName()()执行后);return invoke;}
}interface Movable {void move();
}
CGLIB动态代理
CGLib(Code Generate Library) 与JDK动态代理不同的是cglib生成代理是被代理对象的子类。因此它拥有继承方法实现静态代理的优点不需要被代理对象实现某个接口。 缺点不能给final类生成代理因为final类无法拥有子类。
使用cglib生成代理类也很简单只要指定父类和回调方法即可 首先需要引入依赖
dependencygroupIdcglib/groupIdartifactIdcglib/artifactIdversion3.2.12/version/dependencyimport net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;public class Main {public static void main(String[] args) {Enhancer enhancer new Enhancer(); // 增强者enhancer.setSuperclass(Tank.class); // 指定父类enhancer.setCallback(new TimeMethodInterceptor()); // 当被代理对象的方法调用的时候会调用 该对象的interceptTank tank (Tank)enhancer.create(); // 动态代理的生成tank.move(); // 生成之后会调用}
}class TimeMethodInterceptor implements MethodInterceptor{Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println(生成的类名o.getClass().getName());System.out.println(生成的类的父类o.getClass().getSuperclass().getName());System.out.println(方法执行前被代理的方法method.getName());Object result null;result methodProxy.invokeSuper(o, objects);System.out.println(方法执行后被代理的方法method.getName());return result;}
}
class Tank{public void move(){System.out.println(Tank moving clacla....);}
}