交通设施东莞网站建设,广汉网站,网络营销特点主要有哪些,买房在线咨询代理模式
代理模式使用代理对象来代替真实对象的访问#xff0c;在不修改原有对象的前提下#xff0c;提供额外的操作#xff0c;扩展目标对象的功能。代理模式分为静态代理和动态代理。
静态代理
手动为目标对象中的方法进行增强#xff0c;通过实现相同接口重写方法进…代理模式
代理模式使用代理对象来代替真实对象的访问在不修改原有对象的前提下提供额外的操作扩展目标对象的功能。代理模式分为静态代理和动态代理。
静态代理
手动为目标对象中的方法进行增强通过实现相同接口重写方法进行增强。非常不灵活当对象中新增方法时代理类同样需要增加代理方法。静态代理是在代码编译时生成的代理类
实现步骤
定义接口和实现类定义代理类实现接口将被代理类注入重写方法在方法中增强
代码展示 接口 public interface Image {void display(String name);
}实现类 public class RealImage implements Image {Overridepublic void display(String name) {System.out.println(name display);}
}代理类 public class StaticProxy implements Image {private RealImage realImage;Overridepublic void display(String name) {realImage new RealImage();System.out.println(start);realImage.display(name);System.out.println(end);}public static void main(String[] args) {Image image new StaticProxy();image.display(图片);}
}静态代理简单并且局限性太高一般没有人使用
动态代理
相较于静态代理动态代理更加灵活可以被多个类创建统一代理类。针对实现类和接口分别有JDK动态代理和CGLIB动态代理。动态代理是在运行时动态生成代理类并加载到JVM中去的。
JDK动态代理
JDK动态代理是为已经实现接口的类创建代理类。核心是**InvocationHandler接口和Proxy类。Proxy类用于生成代理对象InvocationHandler接口用于自定义处理逻辑。当我们用Proxy类中的newProxyInstance()方法生成的动态代理对象调用方法时这个方法的调用会转发到InvocationHandler接口中的invoke**方法中来调用。
Proxy 类中使用频率最高的方法是newProxyInstance() 这个方法主要用来生成一个代理对象。 public static Object newProxyInstance(ClassLoader loader,Class?[] interfaces,InvocationHandler h)throws IllegalArgumentException{......}这个方法一共有 3 个参数
loader :类加载器用于加载代理对象。interfaces : 被代理类实现的一些接口h : 实现了 InvocationHandler 接口的对象
要实现动态代理的话还必须需要实现InvocationHandler 来自定义处理逻辑。 当我们的动态代理对象调用一个方法时这个方法的调用就会被转发到实现InvocationHandler 接口类的 invoke 方法来调用。
public interface InvocationHandler {/*** 当你使用代理对象调用方法的时候实际会调用到这个方法*/public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
}invoke() 方法有下面三个参数
proxy :动态生成的代理类method : 与代理类对象调用的方法相对应args : 当前 method 方法的参数
实现步骤
定义接口和实现类自定义**InvocationHandler并重写invoke**方法,在方法中调用被代理的方法并实现自定义处理逻辑通过 Proxy.newProxyInstance(ClassLoader loader,Class?[] interfaces,InvocationHandler h) 方法创建代理对象使用代理对象进行方法调用
代码展示 接口和实现类同上 InvocationHandler /*** author linmeng* date 2023/2/22 00:42*/
public class JdkInvocationHandler implements InvocationHandler {/*** 被代理类**/private Object target;public JdkInvocationHandler(Object target) {this.target target;}/*** Author linmeng* Description * date 2023/2/24 15:57* param proxy 动态生成的代理类* param method 代理方法* param args 方法参数* return java.lang.Object**/Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(调用方法前打印方法名称 method.getName());Object res method.invoke(target, args);System.out.println(调用方法后打印方法名称 method.getName());return res;}
}代理对象生成 import java.lang.reflect.Proxy;/*** author linmeng* date 2023/2/22 00:44*/
public class JDKProxy {public static Object getProxy(Object target) {return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new JdkInvocationHandler(target));}}测试 import org.junit.Test;/*** author linmeng* date 2023/2/22 00:50*/public class JdkTest {Testpublic void jdkTest(){Image proxy (Image) JDKProxy.getProxy(new RealImage());proxy.display(图片);}CGLIB动态代理
当类没有实现接口时是不能用JDK动态代理的。这个时候可以用CGLIB动态代理他是通过继承的方式实现代理。
**在 CGLIB 动态代理机制中 MethodInterceptor 接口和 Enhancer 类是核心。**通过实现MethodInterceptor接口中的intercept方法自定义处理逻辑Enhancer类创建代理类。
你需要自定义 MethodInterceptor 并重写 intercept 方法intercept 用于拦截增强被代理类的方法。
public interface MethodInterceptor
extends Callback{// 拦截被代理类中的方法public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,MethodProxy proxy) throws Throwable;
}obj : 被代理的对象需要增强的对象method : 被拦截的方法需要增强的方法args : 方法入参proxy : 用于调用原始方法
你可以通过 Enhancer类来动态获取被代理类当代理类调用方法的时候实际调用的是 MethodInterceptor 中的 intercept 方法。
实现步骤
实现类自定义MethodInterceptor 并重写 intercept方法自定义增强逻辑通过 Enhancer中的create()方法创建代理对象使用代理对象调用方法
代码展示 实现类 public class RealImage2 {public void display(String name) {System.out.println(name display);}
}自定义MethodInterceptor 并重写 intercept方法 /*** author linmeng* date 2023/2/24 14:10*/
public class CGLIBInterceptor implements MethodInterceptor {/*** param o 被代理对象* param method 被拦截的方法* param objects 方法入参* param methodProxy 用于调用元素方法* return java.lang.Object* Author linmeng* Description* date 2023/2/24 14:11**/Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println(调用方法前打印方法名称 method.getName());Object res methodProxy.invokeSuper(o, objects);System.out.println(调用方法后打印方法名称 method.getName());return res;}
}通过 Enhancer中的create()方法创建代理对象 import net.sf.cglib.proxy.Enhancer;/*** author linmeng* date 2023/2/24 14:15*/
public class CGLIBProxy {public static Object getProxy(Class? clazz) {// 动态代理增强类Enhancer enhancer new Enhancer();// 类加载器enhancer.setClassLoader(clazz.getClassLoader());// 被代理类enhancer.setSuperclass(clazz);// 增强类enhancer.setCallback(new CGLIBInterceptor());// 代理类创建return enhancer.create();}
}使用 import org.junit.Test;/*** author linmeng* date 2023/2/22 00:50*/
public class CGLIBTest {Testpublic void cglibTest(){RealImage2 proxy (RealImage2) CGLIBProxy.getProxy(RealImage2.class);proxy.display(图片);}
}参考链接
Java设计模式Proxy(代理)模式 Java 代理模式详解Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass