首页 > 其他分享 >代理模式

代理模式

时间:2023-03-17 11:57:55浏览次数:38  
标签:对象 Object 代理 接口 模式 param public

动态代理动态的生成代理对象,对满足条件的目标对象皆可以生成代理代理对象, 没有静态代理一个目标类一个代理类的问题 解耦合  

JDK动态代理

需要目标类有实现接口

代理类与目标类实现相同接口

接口

package testJdkProxy;
//jdk动态代理必须使用接口
public interface JDKProxy {
public void sayHelloWorld();
}

 

实现类

package testJdkProxy;
//接口实现,真实主题实现类
public class ImplementClass implements JDKProxy {

    @Override
    public void sayHelloWorld() {
        // TODO Auto-generated method stub
        System.out.println("hello world");
    }

}

设置代理

package testJdkProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//代理,代理操作类
public class DynamicProxy implements InvocationHandler{
//真实对象     (通过实现类实现)
private Object target=null;
//建立代理对象和真实对象之间的关系
/**
 * 
 * @param target 真实对象
 * @return  代理对象 
 */
 //接受真实主题实现类(目标对象),把代理对象下挂在接口下 生成下挂后的代理对象来实例化接口
public Object bind(Object target) {
    //保存真实对象,invoke里面会用到    实例化的真实主题实现类 对象——>指向被代理的真实主题
    this.target=target;
    return Proxy.newProxyInstance(
            //实现类的类加载器      实现类所实现的接口          代理对象     ——>把代理对象下挂在接口下
            target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
//代理逻辑
/**
 * @param proxy 代理对象
 * @param method 当前调度方法
 * @param args 当前方法参数
 * @return 代理结果返回
 * @throws Throwable 异常
 */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // TODO Auto-generated method stub
    System.out.println("进入代理逻辑方法");
    System.out.println("在调度真实对象之前的服务--------");
    //------------------------------------------------------------------执行前业务逻辑
    Object object=method.invoke(target, args); //相当于调用sayhelloworld方法
    //---------------------------------------------------------------------执行后业务逻辑
    System.out.println("在调度真实对象之后的服务");
    //invoke的返回值
    return object;
}

}

 

测试

package testJdkProxy;

public class ToTest {
public static void main(String[] args) {
    new ToTest().testJdkProxy();
}
public void testJdkProxy() {
    //创建代理
        DynamicProxy jdk=new DynamicProxy();
    //绑定关系,实例化接口,下挂代理JDKProxy接口下,通过代理实例化接口对象 
    JDKProxy  pro=(JDKProxy)jdk.bind(new ImplementClass());
    //此时JDKProxy对象已经是一个代理对象,调用方法的时候,他会自动进入代理的逻辑方法invoke里 重复的业务逻辑不用额外手动调用
    pro.sayHelloWorld();
}
}
通过bind方法绑定代理关系,实例化接口对象,调用方法时自动转入 代理逻辑invoke方法

 

 

CGLIB动态代理

只需要一个非抽象类实现MethodInterceptor   使用: 过程:被代理的类——创建代理——使用 依赖:第三方包 要用到 cglib-nodep-2.2.jar 包 实现 代理要implements MethodInterceptor 原理 Cglib代理可以对任何类生成代理,代理的原理是对目标对象进行继承代理, 注意 如果目标对象,被final修饰了,那么该类似无法被cglib代理的    

目标类

package testCGLIBOproxy;

public class ProxyedClass {
    public void sayHello() {
        System.out.println("hellloworld");
    }
}

 

代理类

package testCGLIBOproxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

//CGLIB不需要提供接口,只需要一个非抽象类就能实现动态代理
public class CglibProxyExample implements MethodInterceptor {
    /**
     * 生成代理对象
     * @param cla——Class类
     * @return Class类的CGLIB代理对象
     */
    
    
    public Object getProxy(Class cla) {
        //CGLIB enhancer 增强类对象      加强者
        Enhancer enhancer=new Enhancer();
        //设置代理谁  setSuperclass设置超类  要继承的目标对象
        enhancer.setSuperclass(cla);
        //setCallback设置代理类    定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法
        enhancer.setCallback(this);
        //生成并返回代理对象
        return enhancer.create();
    }
    /**
     * 代理逻辑方法
     * @param arg0代理对象
     * @param arg1方法
     * @param arg2方法参数
     * @param arg3方法代理
     * @return 代理逻辑返回
     * 
     */
    @Override
    public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("调用真实对象前");
        //反射调用真实对象方法 传参数给它
        Object result=arg3.invokeSuper(arg0,arg2);
        //调用真实对象后
        System.out.println("调用真实对象后");
        return result;
    }
    
    
}

 

测试类

package testCGLIBOproxy;

public class TestClass {
public static void main(String[] args) {
    new TestClass().testCGLIB();
}
public void testCGLIB() {
    //创建代理对象
    CglibProxyExample cep=new CglibProxyExample();
    //通过代理实例化被代理对象类
    ProxyedClass obj=(ProxyedClass)cep.getProxy(ProxyedClass.class);
    //与代理关联后,调用方法时,自动进入代理逻辑intercept方法
    obj.sayHello();
}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

标签:对象,Object,代理,接口,模式,param,public
From: https://www.cnblogs.com/deity-night/p/17226155.html

相关文章

  • 观察者模式和发布订阅模式
    首先我们必须清楚这两种模式都是设计模式,而不是某种语言的专属;观察者模式(Observer)概念理解观察者模式是一种一对多的依赖关系的行为设计模式,让多个观察者对象监听一......
  • 设计模式——享元模式
    个人理解:抽离公共方法所需的属性进行共享;不需要的字段抽离到外面进行管理。1、享元模式享元模式(FlyweightPattern)主要用于减少创建对象的数量,以减少内存占用和提高性能......
  • Nginx负载均衡的三种模式
    1、轮询模式轮询模式是根据访问时间,之一分配到不同的后端服务器,并且后端服务器如果down掉了,Nginx还会自动剔除这个失效的地址,适合服务器配置相当,无状态且短平快的服务......
  • ASEMI代理PCF85163T/1,518原装NXP车规级PCF85163T/1,518
    编辑:llASEMI代理PCF85163T/1,518原装NXP车规级PCF85163T/1,518型号:PCF85163T/1,518品牌:NXP/恩智浦封装:SOP-8批号:2023+安装类型:表面贴装型PCF85163T/1,518汽车芯片......
  • ASEMI代理MIMXRT1064CVJ5B原装现货NXP车规级MIMXRT1064CVJ5B
    编辑:llASEMI代理MIMXRT1064CVJ5B原装现货NXP车规级MIMXRT1064CVJ5B型号:MIMXRT1064CVJ5B品牌:NXP/恩智浦封装:LFGBA-196批号:2023+安装类型:表面贴装型引脚数量:196类型......
  • 设计模式5——模板方法模式
    1、定义模板方法模式由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类。2、核心在抽象父类中封装子类的算法框架,它的init方法可作为一个算法的模板,指导子......
  • nginx配置反向代理
         通过docker-compose安装nginx docker-composeup-dnginx 将容器内配置文件卷出来修改nginx/nginx.confusernginx;worker_processes1......
  • 请你谈谈单例模式的优缺点,注意事项,使用场景
    单例模式(Singleton),是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个全局对象,这样有利于我们协调系统整......
  • 爬虫相关 requests高级用法、解析json、ssl认证(了解)、使用代理(重要)、超时设置、
    requests高级用法解析json#发送http请求,返回的数据会有xml格式,也有json格式importrequestsdata={'cname':'','pid':'','keyword':'500','page......
  • 设计模式(二十三)----行为型模式之中介者模式
    1概述一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如在下......