前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >代理模式

代理模式

作者头像
晚上没宵夜
发布2022-05-09 21:04:50
1890
发布2022-05-09 21:04:50
举报

1. 代理模式(Proxy Pattern)

我们需要的东西通过代理对象拿去,而不需要去真正的实现对象,前提是代理对象和被代理对象需要实现相同的接口,而代理在这里相当于中介,并且我们也需要创建一个代理对象

2. 代理的实现

1.2 静态代理

有点类似装饰者模式,话不多说上代码

1.共同的接口

代码语言:javascript
复制
public interface Dog {
	abstract void eat();
}

2.实现类

代码语言:javascript
复制
public class MyDog implements Dog {

	public void eat() {
		System.out.println("狗吃肉");
	}
}

3.代理类

代码语言:javascript
复制
public class DogProxy implements Dog {

	private Dog dog;
	
	public DogProxy (Dog dog) {
		this.dog = dog;
	}
    
    public void WashHand(){
		System.out.println("吃肉前洗手");
	}

	public void eat() {
        WashHand();
		dog.eat();
	}
}

4.代理实现

代码语言:javascript
复制
public static void main(String[] args) {
		
    Dog mydog = new MyDog();
    mydog = new WashHandDog(mydog);
    mydog.eat();
}
代码语言:javascript
复制
吃肉前洗手
狗吃肉

1.3 动态代理

动态代理也是基于接口实现的,所以使用上面的接口,该接口增多一个抽象方法用于下面测试

这里重申一下,生成的代理对象是要强转成接口的,接口,接口!!!

代码语言:javascript
复制
public class MyDog implements Dog {

	public void eat() {
		System.out.println("狗吃肉");
	}

    //测试方法
	public void jump() {
		System.out.println("狗会跳");
	}
}

这里需要先了解两个方法

  • Proxy类的newInstance() ——生成代理对象

该方法有三个参数,第一个是被代理对象的类加载器,第二个是被代理对象的接口,第三个是处理器也就是下面的InvocationHandler()

  • InvocationHandler()——处理器

在代理对象上调用任何方法都会被这个处理器拦截

具体实现

代码语言:javascript
复制
public static void main(String[] args) {
	
    //被代理对象
    Dog mydog = new MyDog();
    
    //生成代理对象,这里InvocationHandler采用匿名函数写法
    Dog ProxyDog = (Dog) Proxy.newProxyInstance(mydog.getClass().getClassLoader(), mydog.getClass().getInterfaces(),new InvocationHandler(){

		//重写方法
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			//只增强eat方法
			if(method.getName().equals("eat")){
				System.out.println("吃肉前洗手");
				method.invoke(mydog, args);
			}else{
				method.invoke(mydog, args);
			}
			return null;
		}
    });
    
    //代理对象调用增强函数
	ProxyDog.eat();
	System.out.println("-------测试方法--------");
	//没有增强
	ProxyDog.jump();
}
代码语言:javascript
复制
吃肉前洗手
狗吃肉
-------测试方法--------
狗会跳
  • Spring的AOP切面编程也是可以用动态代理来实现的,想要了解AOP的 戳这里

回来填坑,之前一直不理解为什么代理对象调用方法就能有方法实现,后面参考了 廖雪峰 的博客豁然开朗 ,这里十分万分感谢

代码语言:javascript
复制
//动态代理实际上是JDK在运行期动态创建class字节码并加载的过程,它并没有什么黑魔法,把上面的动态代理改写为静态实现类大概长这样


public class HelloDynamicProxy implements Hello {
    InvocationHandler handler;
    
    //传入了之前写的处理器
    public HelloDynamicProxy(InvocationHandler handler) {
        this.handler = handler;
    }
    
    //看这里这里没错就是这里!!!,方法中写入invoke,这里就实现调用方法,困惑了我好久
    public void morning(String name) {
        handler.invoke(
           this,
           Hello.class.getMethod("morning"),
           new Object[] { name });
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 代理模式(Proxy Pattern)
  • 2. 代理的实现
    • 1.2 静态代理
      • 1.3 动态代理
      • 这里重申一下,生成的代理对象是要强转成接口的,接口,接口!!!
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档