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

代理模式

时间:2022-10-22 15:44:41浏览次数:38  
标签:target Object System 模式 代理 println public

代理模式

静态代理

优点

业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。代理使客户端不需要知道实现类是什么,怎么做的,而客户端只需知道代理即可(解耦合)

缺点

代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。

接口

public interface Rent {
    void rent();
}

目标类

public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房屋出租");
    }
}

代理类

public class HostProxy implements Rent{
    Host host;
    public HostProxy(Host host1){
        this.host=host1;
    }
    @Override
    public void rent() {
        System.out.println("事务开始");
        host.rent();
        System.out.println("提交");
    }
}

客户

public class Client {
    public static void main(String[] args) {
        //静态代理
        Host host = new Host();
        HostProxy hostProxy = new HostProxy(host);
        hostProxy.rent();
    }
}

动态代理

jdk实现

需要被代理类实现有接口,然后通过Proxy类的newProxyInstance(ClassLoader loader,Class<?> interface,InvocationHandler h)方法创建

接口

public interface UserDao {
    int add(int a,int b);
    String paste(String str);
}

被代理类:需要有实现接口

public class User implements UserDao{
    @Override
    public int add(int a, int b) {
        return a+b;
    }
    @Override
    public String paste(String str) {
        return str;
    }
}

代理类:需要传入被代理的对象

newProxyInstance方法参数解释ClassLoader loader,Class<?> interface,invocationHandler h

ClassLoader loader:获取类加载器

Class<?> interface:被代理类的接口类型,可以是一个数组

InvocationHandler h:具体执行代理的接口

public class UserProxy {
    private Object target;
    public UserProxy(Object obj){
        target = obj;
    }
    public Object getProxy(){
        return Proxy.newProxyInstance(UserDao.class.getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object invoke = null;
                System.out.println(method.getName());
                if (method.getName().equals("add")){
                    System.out.println("开始增强");
                    invoke = method.invoke(target, args);
                    System.out.println("方法执行完毕");
                }
                return invoke;
            }
        });
    }
}

客户端调用以及结果输出

cglib实现

此方式不要求被代理类为接口的实现类,cglib基于继承被代理类实现的

需要先引入相关依赖

<dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.1</version>
        </dependency>

被代理的类

public class HelloCglib {
        public void sayHello() {
            System.out.println("CGLIB动态代理模式!");
        }
}

cglib代理类

public class CglibProxy implements MethodInterceptor {
    /**
     * 指定cglib代理模式的代理类
     */
    private final Object target;

    public CglibProxy(Object target) {
        this.target = target;
    }
    public Object getProxy() {
        Enhancer enhancer = new Enhancer();
        //设置超类方法
        enhancer.setSuperclass(this.target.getClass());
        //设置一个回调方法,用来设置哪个类为代理类,this表示当前类为代理类
        enhancer.setCallback(this);
        //创建代理对象
        return enhancer.create();
    }
    public Object intercept(Object obj,
                            Method method, Object[] args,
                            MethodProxy proxy) throws Throwable {
        System.out.println("CGLIB代理前");
        Object object = proxy.invokeSuper(obj, args);
        System.out.println("CGLIB代理后");
        return object;
    }
}

客户端演示

public class HelloClient {
    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy(new HelloCglib());
        HelloCglib proxy = (HelloCglib) cglibProxy.getProxy();
        proxy.sayHello();
    }
}

.

标签:target,Object,System,模式,代理,println,public
From: https://www.cnblogs.com/happy12123/p/16816016.html

相关文章

  • ON/安森美ISL9R3060G2车规FRD,原厂渠道ASEMI代理
    编辑-ZON/安森美ISL9R3060G2车规FRD参数:型号:ISL9R3060G2重复峰值反向电压(VRRM):600V平均正向电流(IF):30A浪涌非重复正向电流(IFSM):325A功耗(PD):200W操作和储存温度范围(TJ,T......
  • 8_vue是如何代理数据的
    在了解了关于js当中的Object.defineProperty()这个方法后,我们继续对vue当中的数据代理做一个基于现在的解析建议观看之前先了解下js当中的Obejct.defineProperty()链接地......
  • 设计模式之工厂方法模式
    简介在简单工厂模式中只提供一个工厂类,该工厂类处于对产品类进行实例化的中心位置,它需要知道每一个产品对象的创建细节,并决定何时实例化哪一个产品类。简单工厂模式最大的......
  • STW43NM60ND意法车规MOS管\原装现货ASEMI代理
    编辑:llSTW43NM60ND意法车规MOS管\原装现货ASEMI代理型号:STW43NM60ND品牌:ASEMI封装:TO-247最大漏源电流:35A漏源击穿电压:600VRDS(ON)Max:0.08Ω引脚数量:3特性:车规级MOS......
  • STW43NM60ND意法车规MOS管\原装现货ASEMI代理
    编辑:llSTW43NM60ND意法车规MOS管\原装现货ASEMI代理型号:STW43NM60ND品牌:ASEMI封装:TO-247最大漏源电流:35A漏源击穿电压:600VRDS(ON)Max:0.08Ω引脚数量:3特性:车规级MOS管芯片个数:......
  • STW78N65M5意法车规MOS管\原装现货\ASEMI代理
    编辑:llSTW78N65M5意法车规MOS管\原装现货\ASEMI代理型号:STW78N65M5品牌:ASEMI封装:TO-247最大漏源电流:69A漏源击穿电压:650VRDS(ON)Max:0.24Ω引脚数量:3沟道类型:N沟道MOS管芯片尺......
  • 14*4点 LCD液晶显示驱动控制电路(IC)-VK1S56D SSOP24 0.635脚距,多用于美容仪器/电池电
    产品品牌:永嘉微电/VINKA产品型号:VK1S56D封装形式:SSOP24(脚位间距:0.635mm)概述:VK1S56DSSOP24是一个点阵式存储映射的LCD驱动器,可支持最大56点(14SEGx4COM)的LCD屏,也支......
  • Spring Cloud集成Seata分布式事务-TCC模式
    参考文章分布式事务实战方案汇总https://www.cnblogs.com/yizhiamumu/p/16625677.html分布式事务原理及解决方案案例 https://www.cnblogs.com/yizhiamumu/p/16662412.......
  • 移动光猫改桥接模式--获得移动ipv6公网ip地址
         事实上现今许多网络服务提供商(ISP)都提供了IPV6地址,你手机连上移动、联通、电信的基站,都能获取到一个IPV6地址,没道理宽带不给提供啊。  其实啊,许多发展还不......
  • 代理模式
    婚介所其实就是找对象的一个代理,请仿照我们的课堂例子“论坛权限控制代理”完成这个实际问题,其中如果年纪小于18周岁,婚介所会提示“对不起,不能早恋!”,并终止业务。  ......