动态代理

动态代理

为什么需要代理

对象如果嫌身上干的事太多,可以通过代理来转移部分职责;对像有什么方法想被代理,代理就一定要有对应的方法。

入门案例

一个歌手能唱歌和跳舞,代理人为他代理相应的唱歌跳舞业务。

创建歌手类,会唱歌和跳舞:

public class BigSinger implements Singer{
	private String name;

	public Singer(name) {
		this.name = name;
	}

	public String sing(String name) {
		System.out.println(this.name + "正在唱:" + name);
		return "谢谢";
	}

	public void dance(String name) {
		System.out.println(this.name + "正在跳舞:");
	}
}

创建接口表示该歌手要代理的业务

public interface Singer {

	String sing(String name);
	void dance();
}

创建代理类

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

public class ProxyUtil {
	public static Singer createProxy(BigSinger bigSinger){
	/**
	 * newProxyInstance(ClassLoader loader,
	 *     Class<?>[] interfaces,
	 *     InvocationHandler h)
	 *     参数1: 用于制定一个类加载器
	 *     参数2:指定生成的代理长什么样子,也就是有哪些方法
	 *     参数3:用来指定生成的对象要干什么事情
	 */
		Singer singerProxy = (Singer) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
		new Class[]{Singer.class}, new InvocationHandler() {
		@Override // 回调方法
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// 代理对象要做的事情,会在这里写代码
		if(method.getName().equals("sing")){
			System.out.println("准备话筒,收钱20万");
		}else if(method.getName().equals("dances")){
			System.out.println("准备场地,收钱1000万")
		}
			return method.invoke(bigSinger, args);
		}
		});
		return singerProxy;
	}
}

编写测试类

public class Test{
	BigSinger s = new BigSinger("张学友");
	Singer singerProxy = ProxyUtil.createProxy(s);

	String rs = startProxy.sing("吻别");
	System.out.println(rs);
}