代理模式

代理模式(Proxy pattern)

概念

核心作用

应用场景

分类

案例(明星代理)

静态代理

动态代理

JDK的Proxy方式实现动态代理

方法

案例

UML类图


代理模式(Proxy pattern)

  • 概念

张学友代理人!张学友只负责唱歌!面谈,签合同,安排飞机车辆,收款等其他任务全部丢给代理人

术语:通过代理,控制对对象的访问

  • 核心作用

将统一的流程控制放到代理角色中处理!可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理(即AOP的微观实现)

AOP(Aspect Oriented Propramming 面向切面编程)的核心实现机制!

  • 应用场景

1:安全代理,屏蔽对真实角色的直接访问

2:远程代理,通过代理类处理远程方法调用(RMI)

3:延迟代理,先加载轻量级的代理对象,真正需要再加载真实对象

  • 分类

1:静态代理(静态定义代理类)

2:动态代理(动态生成代理类)

         (1)JDK自带的动态代理(常用

         (2)Javaassist字节码操作库实现

         (3)CGLIB

         (4)ASM,底层使用指令,可维护性较差

  • 案例(明星代理)

  • 静态代理

定义明星接口

public interface Star {
	//面谈
	public abstract void confer();
	//签合同
	public abstract void contract();
	//订票
	public abstract void book();
	//唱歌
	public abstract void sing();
	//收钱
	public abstract void collect(); 
}

定义真实明星类

public class RealSta implements Star{

	public void confer() {
		System.out.println("RealSta.confer()");
	}

	public void contract() {
		System.out.println("RealSta.contract()");
	}

	public void book() {
		System.out.println("RealSta.book()");
	}

	public void sing() {
		System.out.println("张学友--饿狼传说");
	}

	public void collect() {
		System.out.println("RealSta.collect()");
	}

}

定义代理明星(除了唱歌外,其他工作都可做)

/*
 * 明星代理除了不能唱歌,其他工作都可以去做
 */
public class StarProxy implements Star{
	private Star star;
	
	
	public StarProxy(Star star) {
		super();
		this.star = star;
	}

	public void confer() {
		System.out.println("StarProxy.confer()");
	}

	public void contract() {
		System.out.println("StarProxy.contract()");
	}

	public void book() {
		System.out.println("StarProxy.book()");
	}
	//代理不会唱歌,要调用明星的sing()方法
	public void sing() {
		star.sing();
	}

	public void collect() {
		System.out.println("StarProxy.collect()");
	}

}

客户端测试

public class Client {

	public static void main(String[] args) {
		Star star = new RealStar();
		StarProxy proxy = new StarProxy(star);
		proxy.confer();
		proxy.contract();
		proxy.book();
		proxy.sing();
		proxy.collect();
	}

}

console:
StarProxy.confer()
StarProxy.contract()
StarProxy.book()
张学友--饿狼传说
StarProxy.collect()
  • 动态代理

/*
 * 动态代理
 */

public class StarHandler implements InvocationHandler{
	private Star star;
	
	public StarHandler(Star star) {
		super();
		this.star = star;
	}

	//核心方法
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		method.invoke(star, args);
		return null;
	}

}

客户端测试

public class Client {

	public static void main(String[] args) {
		Star star = new RealStar();
		StarHandler handler = new StarHandler(star);
		Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler);
		proxy.confer();
		proxy.contract();
		proxy.book();
		proxy.sing();
		proxy.collect();
	}

}

 

  • JDK的Proxy方式实现动态代理

  • ​​​​​​​方法

static Object

newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

返回值:Object就是代理对象

参数    :loader:代表与目标对象相同的类加载器-------目标对象.getClass().getClassLoader()

               interfaces:代表与目标对象实现的所有的接口字节码对象数组-----目标对象.getClass().getInterfaces()

               h:具体的代理的操作,InvocationHandler接口-----new InvocationHandler(){}

注意:JDK的Proxy方式实现的动态代理 目标对象必须有接口 没有接口不能实现jdk版动态代理

  • 案例

目标接口

public interface TargetInterface {
	
	public void method1();
	public String method2();
	public int method3(int num);
}

目标类实现接口

public class Target implements TargetInterface{

	@Override
	public void method1() {
		System.out.println("method1 is running!");
	}

	@Override
	public String method2() {
		System.out.println("method2 is running!");
		return "mark";
	}

	@Override
	public int method3(int num) {
		System.out.println("method3 is running!");
		return num;
	}
	
}

Proxy动态代理

//动态创建代理对象
public class ProxyMark {
	public static void main(String[] args) {

		// 需要调用方法的目标对象
		final Target target = new Target();
		TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(target
				.getClass().getClassLoader(),
				target.getClass().getInterfaces(), new InvocationHandler() {

					@Override
					// 被执行几次?------- 看代理对象调用方法几次
					// 代理对象调用接口相应方法 都是调用invoke
					/*
					 * proxy:是代理目标对象 method:代表的是目标方法的字节码对象 args:代表是调用目标方法时参数
					 */
					public Object invoke(Object proxy, Method method,
							Object[] args) throws Throwable {
						// 反射
						Object invoke = method.invoke(target, args);// 目标对象的相应方法
						// retrun返回的值给代理对象
						return invoke;
					}
				});
		proxy.method1(); // 调用invoke---Method:目标对象的method1方法 args:null 返回值null
		String str = proxy.method2(); // 调用invoke---Method:目标对象的method2方法
										// args:null 返回值mark
		System.out.println(str);
		int num = proxy.method3(10); // 调用invoke-----Method:目标对象的method3方法
										// args:Object[]{100} 返回值100
		System.out.println(num);

	}
}
  • UML类图

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值