动态代理分为两个部分:
1、动态
(1)一个代理对象(比如娱乐圈的经纪人)可以代理多个被代理对象
(2)被代理对象的多个行为可以被代理
2、代理
被代理对象是真实实现功能的人,代理对象只是增强被代理对象的功能。这里的增强是指在被代理对象实现功能的前后,设置一些
其他的行为,比如在胡歌表演(调用被代理对象的行为)前收钱,在胡歌表演后要求追加合同。
第一步:
public interface Ihuge {
//定义一个接口:被代理人需要被代理的功能
void sing(int money);
void dance(int money);
void act(int money);
}
第二步:
public class Huge implements Ihuge {
/*定义被代理对象(比如胡歌)的行为:
1、需要交给代理对象代理的行为:
sing、dance、act 和对应的接口中的行为一致
2、不需要交给代理人代理的行为
自然不用写入接口
*/
@Override
public void sing(int money) {
System.out.println("胡歌演唱仙剑主题曲");
}
@Override
public void dance(int money) {
System.out.println("胡歌跳钢管舞");
}
@Override
public void act(int money) {
System.out.println("胡歌拍新戏");
}
public void show(){
System.out.println("胡歌要走秀");
}
第三步:代理对象必须要实现InvocationHandler(调用处理器)的功能,实现其中的invoke方法
public class Agent implements InvocationHandler {
private Object obj;//被代理对象的实例
public Agent() {
}
//代理对象的无参构造
public Agent(Object obj) {
this.obj = obj;
}
//代理对象的有参构造
@Override
/*Object proxy 暂时不用管什么意思,不影响使用
Method method 描述代理对象可以增强哪些功能(比如有的经纪人只代理明星的唱歌业务)
Object[] args 参数的集合(被代理对象的被代理方法里的参数,如明星唱歌要收费等)
**/
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
/*在实现invoke(即被代理对象的行为--唱歌、跳舞之前),代理对象需要增强的行为写在前面;
同理,之后要增强的行为写在invoke行之后
**/
/*如果对被代理对象的不同行为有不同的增强,就使用if,获取方法名,然后针对性地操作
如代理唱歌,抽一成,事后签演唱会合同;
代理跳舞,抽两成,事后签商演合同;
*/
Object invoke=null;
/*定义invoke接受 invoke方法的返回值对象——即调用的具体method的返回值对象,
如sing的返回值是void,那这里返回值是null.
*/
if ("sing".equals(method.getName())){
System.out.println("经纪人抽取了" + ((int)((int)(args[0]) * 0.1)) + "元钱");
invoke=method.invoke(obj,args);//输入对象实例(测试类中new一个胡歌)和参数,有异常抛出即可
System.out.println("签订演唱会合同");
return invoke;
}
//除了唱歌以外,代理人的增强方式一样
System.out.println("经纪人收取代理费10000元,一次性收取到位");
invoke=method.invoke(obj,args);
System.out.println("演出后,大家纷纷鼓掌");
return invoke;
}
}
第四步:测试类
public class Test {
public static void main(String[] args) {
Huge huge = new Huge();//创建被代理对象的实例
Ihuge ihuge = (Ihuge)Proxy.newProxyInstance(huge.getClass().getClassLoader(),
huge.getClass().getInterfaces(), new Agent(huge));
/*Proxy.newProxyInstance
需要三个参数:类加载器、被代理兑现所实现的所有接口,代理接口
创建一个代理功能的对象,强转为需要增强的功能的接口Ihuge
*/
//调用功能即可
ihuge.sing(10000);
ihuge.dance(20000);
ihuge.act(100000);
}
}