代理模式

代理模式是经典的设计模式之一,目的是为了扩展和增强类或接口。代理模式通常分为静态代理模式和动态代理模式。

1.1 静态代理模式

静态代理模式的实现比较简单,主要的实现原来是:代理类与被代理类同时实现一个主题接口,代理类持有被代理类的引用

1、例如声明一个接口:

//声明一个公共的接口
public interface UserInterface {
    public abstract void getUser();
}

2、定义真实的执行类RealUser并实现公共接口:

//真实执行类---被代理类
public class RealUser implements UserInterface{
    @Override
    public void getUser() {
        System.out.println("真实用户角色执行");
        UserServices userServices = new UserServices();
        userServices.setId(1);
        userServices.setName("hhhh");
        userServices.getUser();
    }

}

3、定义代理类UserProxy实现公共接口,并持有被代理类的实例,在执行时,调用被代理类实例的getUser( )方法:

//声明代理类
public class UserProxy implements UserInterface{
    private UserInterface userInterface;
    //构造方法传入UserInterface类型参数
    public UserProxy(UserInterface userInterface){
        this.userInterface = userInterface;
    }
    //实现getUser()方法,在执行方法前后进行额外操作
    @Override
    public void getUser() {
        doBefore();
        userInterface.getUser();
        doAfter();
    }

    private void doBefore() {
        System.out.println("代理类开始执行");
    }

    private void doAfter() {
        System.out.println("代理类结束执行");
    }
}

 写一个测试类,打印结果:

public class SpringProxyTest {
    public static void main(String[] args) {
        UserInterface realUser = new RealUser();
        //传入真实对象RealUser
        UserProxy userProxy = new UserProxy(realUser);
        userProxy.getUser();
    }
}


代理类开始执行
真实用户角色执行
id:1
name:hhhh
代理类结束执行

代理类实际上时被调用了被代理类的方法。

2.1 动态代理类

1、动态代理是指在程序运行时动态创建代理类。动态代理的使用方式分两种:一种是基于接口的代理。另一种是基于类的代理。

基于接口的代理方式:通过JDK自带的反射类来生成动态代理类。

基于类的代理方式:通过字节码处理来实现类代理,如CGlib和JAVAssist。

2、基于JDK反射生成代理类的例子:定义一个接口:

//公共接口
public interface UserServiceInterface {
    public void getUser();
}

定义一个真实用户角色类UserServiceImpl实现接口:

//定义真实用户角色类,并实现接口
public class UserServiceImpl implements UserServiceInterface{
    //实现方法
    @Override
    public void getUser() {
        System.out.println("zhang san");
    }
}

定义一个代理类UserServiceProxy,实现InvocationHandler接口,重写方法:

//定义代理类
public class UserServiceProxy implements InvocationHandler {
    private Object target;
    //构造方法
    public UserServiceProxy(Object target){
        this.target = target;
    }
    //通过Proxy动态生成代理类对象
    public<T> T getProxy(){
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
    }
    //动态执行方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("JDK before");
        method.invoke(target,args);
        System.out.println("JDK after");
        return null;
    }
}

Proxy类的设计用到代理模式的设计思想,Proxy类对象实现了代理目标的所有接口,并代替目标对象进行实际的操作。但这种替代不是一种简单的替代,这样没有任何意义,代理的目的是在目标对象方法的基础上作增强,这种增强的本质通常就是对目标对象的方法进行拦截。所以,Proxy应该包括一个方法拦截器,来指示当拦截到方法调用时作何种处理。InvocationHandler就是拦截器的接口。

Object invoke(Object  proxy, Method  method, Object[]  args)

这三个参数:第一个: Object  proxy--在其上调用方法的代理实例--也就是真实的实现类

第二个:Method  method---对应于在代理实例上调用的接口方法的 Method 实例。 Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。---也就是重写的方法

第三个:Object[]  args--- 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类。

写一个测试类:

public class SpringProxyTest {
    public static void main(String[] args) {
        //通过代理类生产UserServiceInterface接口类型对象
        UserServiceInterface userServiceInterface = new UserServiceProxy(new UserServiceImpl()).getProxy();
        //调用getUser( )方法
        userServiceInterface.getUser();
    }
}

JDK before
zhang san
JDK after

根据打印结果,真实用户角色类被屏蔽了,只需要暴露接口即可执行成功,屏蔽内部实现的逻辑就是代理模式的特点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值