代理模式的基本介绍:
静态代码模式的基本介绍:
静态代理应用实例:
ITeacherDao:定义抽象的方法(授课)规范
//接口
public interface ITeacherDao {void teach(); // 授课的方法}
TeacherDao:实现具体的业务功能
public class TeacherDao implements ITeacherDao {@Overridepublic void teach() {System.out.println(" 老师授课中 。。。。。");}}
TeacherDaoProxy:代理类,聚合了一个 ITeacherDao 具体实现类的对象,在TeacherDaoProxy实现了 ITeacherDao 接口,并在 teach() 方法中完成代理操作
//代理对象,静态代理
public class TeacherDaoProxy implements ITeacherDao {private ITeacherDao target; // 目标对象,通过接口来聚合// 构造器public TeacherDaoProxy(ITeacherDao target) {this.target = target;}@Overridepublic void teach() {System.out.println("开始代理 完成某些操作。。。。。 ");// 方法target.teach();System.out.println("提交。。。。。");// 方法}}
Client:客户端
public class Client {public static void main(String[] args) {// 创建目标对象(被代理对象)TeacherDao teacherDao = new TeacherDao();// 创建代理对象, 同时将被代理对象传递给代理对象TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);// 通过代理对象,调用到被代理对象的方法// 即:执行的是代理对象的方法,代理对象再去调用目标对象的方法teacherDaoProxy.teach();}}
静态代理优缺点:
动态代理模式的基本介绍:
JDK中生成代理对象的API:
static Object newProxyInstance(ClassLoader loader, Class>[] interfaces, InvocationHandler h)
动态代理应用实例:
ITeacherDao
//接口
public interface ITeacherDao {void teach(); // 授课方法void sayHello(String name);}
TeacherDao:
public class TeacherDao implements ITeacherDao {@Overridepublic void teach() {System.out.println(" 老师授课中.... ");}@Overridepublic void sayHello(String name) {System.out.println("hello " + name);}}
ProxyFactory:通过构造器传入被代理对象,通过 Proxy.newProxyInstance() 方法中的 new InvocationHandler() 匿名内部类实现具体的代理逻辑
public class ProxyFactory {// 维护一个目标对象 , Objectprivate Object target;// 构造器 , 对target 进行初始化public ProxyFactory(Object target) {this.target = target;}// 给目标对象 生成一个代理对象public Object getProxyInstance() {// 说明/** public static Object newProxyInstance(ClassLoader loader, Class>[] interfaces, InvocationHandler h)* * 1. ClassLoader loader : 指定当前目标对象使用的类加载器, 获取加载器的方法固定 * 2. Class>[] interfaces: 目标对象实现的接口类型,使用泛型方法确认类型 * 3. InvocationHandler h : 事情处理,执行目标对象的方法时,会触发事情处理器方法, 会把当前执行的目标对象方法作为参数传入*/return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),new InvocationHandler() {@Override/** proxy:proxy the proxy instance that the method was invoked on* method:待调用的目标方法(target 的方法)* args:方法参数*/public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("JDK代理开始~~");// 反射机制调用目标对象的方法Object returnVal = method.invoke(target, args);System.out.println("JDK代理提交");return returnVal;}});}}
Client:
public class Client {public static void main(String[] args) {// 创建目标对象ITeacherDao target = new TeacherDao();// 给目标对象,创建代理对象, 可以转成 ITeacherDaoITeacherDao proxyInstance = (ITeacherDao) new ProxyFactory(target).getProxyInstance();// proxyInstance=class com.sun.proxy.$Proxy0 内存中动态生成了代理对象System.out.println("proxyInstance=" + proxyInstance.getClass());// 通过代理对象,调用目标对象的方法proxyInstance.teach();proxyInstance.sayHello(" tom ");}}
代码追踪:
public final class Method extends Executable {private Class<?> clazz;private int slot;// This is guaranteed to be interned by the VM in the 1.4// reflection implementationprivate String name;private Class<?> returnType;private Class<?>[] parameterTypes;private Class<?>[] exceptionTypes;private int modifiers;// Generics and annotations supportprivate transient String signature;// generic info repository; lazily initializedprivate transient MethodRepository genericInfo;private byte[] annotations;private byte[] parameterAnnotations;private byte[] annotationDefault;private volatile MethodAccessor methodAccessor;
Cglib代理模式的基本介绍:
Cglib代理模式实现步骤&#xff1a;
Cglib代理模式应用实例:
TeacherDao&#xff1a;被代理类
public class TeacherDao {public String teach() {System.out.println(" 老师授课中 &#xff0c; 我是cglib代理&#xff0c;不需要实现接口 ");return "hello";}}
ProxyFactory&#xff1a;代理工厂类&#xff0c;用于获取代理对象
public class ProxyFactory implements MethodInterceptor {// 维护一个目标对象private Object target;// 构造器&#xff0c;传入一个被代理的对象public ProxyFactory(Object target) {this.target &#61; target;}// 返回一个代理对象: 是 target 对象的代理对象public Object getProxyInstance() {// 1. 创建一个工具类Enhancer enhancer &#61; new Enhancer();// 2. 设置父类enhancer.setSuperclass(target.getClass());// 3. 设置回调函数enhancer.setCallback(this);// 4. 创建子类对象&#xff0c;即代理对象return enhancer.create();}// 重写 intercept 方法&#xff0c;会调用目标对象的方法&#64;Overridepublic Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {System.out.println("Cglib代理模式 ~~ 开始");Object returnVal &#61; method.invoke(target, args);System.out.println("Cglib代理模式 ~~ 提交");return returnVal;}}
Client&#xff1a;客户端
public class Client {public static void main(String[] args) {// 创建目标对象TeacherDao target &#61; new TeacherDao();// 获取到代理对象&#xff0c;并且将目标对象传递给代理对象TeacherDao proxyInstance &#61; (TeacherDao) new ProxyFactory(target).getProxyInstance();// 执行代理对象的方法&#xff0c;触发intecept 方法&#xff0c;从而实现 对目标对象的调用String res &#61; proxyInstance.teach();System.out.println("res&#61;" &#43; res);}}
代码追踪&#xff1a;
public final class Method extends Executable {private Class<?> clazz;private int slot;// This is guaranteed to be interned by the VM in the 1.4// reflection implementationprivate String name;private Class<?> returnType;private Class<?>[] parameterTypes;private Class<?>[] exceptionTypes;private int modifiers;// Generics and annotations supportprivate transient String signature;// generic info repository; lazily initializedprivate transient MethodRepository genericInfo;private byte[] annotations;private byte[] parameterAnnotations;private byte[] annotationDefault;private volatile MethodAccessor methodAccessor;
几种常见的代理模式介绍——几种变体&#xff1a;