代理模式与动、静态代理

代理模式与动、静态代理

​ 最近正在纠结考研还是找工作,数学与数据结构都不想学,烦心之下,学点jvav冷静一下,本篇博文主要是讲代理模式以及java中如何用反射机制实现动态代理,大部分瞎比分析都在代码注释里面哈!

代理模式的概念:

Proxy Pattern,是23种经典模式种的一种。

在这里插入图片描述

在调用方与被调用方中间增加一层代理对象,从而实现调用方与被调用方之间的解耦

为目标对象提供一个代理,这个代理可以控制对目标对象的访问,外界不用直接访问目标对象,而是访问代理对象,代理对象再调用目标对象。且代理对象中可以添加监控和审查处理

计算机里,没有什么问题是加一层解决不了的, 如果有的话,只会是加一层后引起新的问题。(啊哈哈哈,wdnmd)

静态代理

代理对象持有目标对象的句柄。(被代理的对象会被当做一个成员变量放在代理对象里面)

所有调用目标对象的方法,都改用调用代理对象的方法。

对每一个方法都需要静态编码(理解简单,但是代码繁琐)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

public interface Subject {
	public void request();

}
public class SubjectImpl implements Subject{

	
	public void request() {
		// TODO Auto-generated method stub
		System.out.println("subjectimpl");
	}

}

public class StaticProxy implements Subject{
	private Subject subject;
	
	public StaticProxy(Subject subject) {
		this.subject = subject;
	}
	
	public void request() {
		// TODO Auto-generated method stub
		System.out.println("preprocess");
		subject.request();
		System.out.println("afterprocess");
	}

}

public class StaticProxyDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SubjectImpl s = new SubjectImpl();
		StaticProxy sp = new StaticProxy(s);
		sp.request();
	}

}

动态代理

为了避免对每个方法进行包装,动态代理被设计而出。

对目标对象的方法每次被调用,进行动态拦截

在这里插入图片描述

动态代理流程图

在这里插入图片描述

首先是被代理对象的接口

public interface Subject {
	public void request();

}

被代理对象

public class SubjectImpl implements Subject{
	public void request() {
		// TODO Auto-generated method stub
		System.out.println("subjectimpl");
	}

}

代理处理器,其中的invoke方法里,有代理时需要进行的操作。

分为before与after以及around等操作。

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

//实现了InvocationHandler接口,
public class ProxyHandler implements InvocationHandler {
    //将Subject接口作为一个内部成员变量,组合起来
    private Subject subject;
    //定义一个构造器,方便Subject的子类进行赋值传入
    public ProxyHandler(Subject subject){
        this.subject = subject;
    }

    //实现InocationHandler接口,需要重写invoke方法,该方法由三个参数
    /**
     *
     * @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());


        System.out.println("before");
        //这句话相当于是 Object result = xx类.xx方法(args);只不过是通过反射来做的。
        Object result = method.invoke(subject,args);
        System.out.println("after");
        return result;
    }
}

main中生成代理对象,并且完成调用

import java.lang.reflect.Proxy;

public class DynamicPoxyDemo {
    public static void main(String[] args) {
        //创造一个实现了Subject接口的对象
        SubjectImpl realSubject = new SubjectImpl();
        
        //将上面的对象交给代理处理器对象接管。
        //代理处理器对象
        ProxyHandler handler = new ProxyHandler(realSubject) ;

        //代理处理器对象再交给代理对象接管。Proxy对象生成实例时候需要三个参数:
        //1.生成代理对象使用哪一个类加载器 
        //2.生成哪一个对象的对象代理,通过接口来指定 
        //3.生成的代理对象的方法里需要干什么事情,由开发人员来编写Handler接口实现来指定。
        //动态生成代理对象
        Subject proxySubject =
                (Subject) Proxy.newProxyInstance(
                        SubjectImpl.class.getClassLoader(),
                        SubjectImpl.class.getInterfaces(),handler
                );


        proxySubject.request();
        System.out.println(proxySubject.getClass().getName());
    }
}

附带两张图,方便食用。

在这里插入图片描述

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值