Java 代理模式

3 篇文章 0 订阅

代理模式分为静态代理和动态代理

静态代理

介绍

类似于生活中的中介代理房东租房、婚介代理要结婚的情侣布置婚礼现场等等。

实现

拿房东租房为例

Rent接口

package com.curtian.study.static_proxy.demo1;

public interface Rent {

    void rent();
}

Rent接口的第一个实现类,房东

package com.curtian.study.static_proxy.demo1;

/**
 * 房东
 */
public class Host implements Rent{

    @Override
    public void rent() {
        System.out.println("房东租房子");
    }
}

Rent接口的第二个实现类,中介

package com.curtian.study.static_proxy.demo1;

public class Proxy implements Rent{

    private Host host;

    @Override
    public void rent() {
        seeHouse();
        host.rent();
        hetong();
        rate();
    }

    public Proxy(Host host) {
        this.host = host;
    }

    private void seeHouse(){
        System.out.println("中介带看房子");
    }

    private void hetong(){
        System.out.println("签署租赁合同");
    }

    private void rate(){
        System.out.println("收取中介费");
    }

}

从代码中我们也可以发现,中介只是在被代理的类的方法上加了一些额外的方法(seeHouse、hetong、rate)

静态代理总结

接口(Rent租房接口)真实角色(Host房东)代理角色(Proxy房屋中介)组成。

好处

是可以是使真实角色操作更加存粹(房东只管租房一件事情),很明显的体现了面向对象七大原则的单一职责原则。公共业务就交给代理角色。

缺点

一个真实角色就对应一个代理角色,比如房东对应房屋中介、要结婚的情侣对应婚介所

动态代理

介绍

拥有静态代理的所有优点以及可以动态生成代理类。

分类

动态代理分为三大类:

  • 基于接口的:jdk动态代理
  • 基于类的:cglib
  • java字节码实现的:javasist

JDK动态代理

(目前博主只了解了jdk动态代理)

JDK动态代理核心

Proxy类InvocationHandler接口
Proxy用于生成代理类,实现InvocationHandler接口可以通过反射获取被代理的类的方法, 然后在此基础上添加一些附属操作

举例

给所有类的方法加一些日志。

UserService接口
package com.curtian.study.static_proxy.demo2;

public interface Userservice {

    void add();

    void delete();
}
UserServiceImpl类
package com.curtian.study.static_proxy.demo2;

import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements Userservice{
    @Override
    public void add() {
        System.out.println("加法");
    }

    @Override
    public void delete() {
        System.out.println("减法");
    }
}

ProxyInvocationHandler(核心)
package com.curtian.study.dynamic_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyInvocationHandler implements InvocationHandler {

    //被代理的对象
    private Object target;

    public void setTarget(Object target){
        this.target = target;
    }

    /**
     * 生成代理类
     * @return
     */
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    /**
     * 当代理类执行方法的时候,会回调到这个方法,附属操作也是在这里加的
     * @param proxy
     * @param method
     * @param args
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(proxy.getClass().getName());
        log("调用了" + method.getName() + "方法");
        return method.invoke(target, args);
    }

    private void log(String msg){
        System.out.println(msg);
    }
}
Test(测试)
/**
 * 动态代理
 * 介绍:动态代理和静态代理角色一样
 * 动态代理的代理类是动态生成的,不是我们直接写好的!
 * 动态代理分为两大类:基于接口的动态代理,基于类的动态代理。
 *      1.基于接口--Jdk动态代理【本次示例】
 *      2.基于类:cglib
 *      3.java字节码实现: javasist
 * 示例中的两个核心类/接口,Proxy类、invocationHandler接口
 *
 * */
public class Main {
    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();
        ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
        proxyInvocationHandler.setTarget(userService);
        Userservice proxy = (Userservice) proxyInvocationHandler.getProxy();
        proxy.add();
        proxy.delete();
    }
}

运行情况:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值