上次的静态代理增强方法全是自己手动写出来的,如果有许多方法,都需要自己一个一个写,显然太麻烦了,这时就可以用到动态代理,制定规则,所有方法统一实现,这次先用proxy实现
除了静态代理类方法别的都一样
Singer接口
public interface Singer {
void sing();
void dance();
}
目标类
public class ZStar implements Singer{
@Override
public void sing() {
System.out.println("我在唱歌.......");
}
@Override
public void dance() {
System.out.println("我在跳舞......");
}
}
方法规则 StarRulerProxy
public class StarRulerProxy implements InvocationHandler {
private Singer singer;//需要实现的接口类
public StarRulerProxy(Singer singer) {
this.singer = singer;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("经纪人商量合同");
method.invoke(singer,args);
System.out.println("经纪人收钱");
return null;
}
}
查看InvocationHandler接口源码中的方法,可以看见只有invoke接口方法,所以只需要实现invoke方法就行,invoke不需要我们用代码调用,他自己会调用
// 其中invoke的传参含义
Object proxy :构造方法中singer指代的对象
Method method 是在运行时对象运行的方法,就比如我主方法中调用dance方法,传入的就是dance
Object[] args:是指在在调用方法时传入的参数,由于我在写接口是都未添加传参,所以在这不传值为null
主方法运行
public class Test {
public static void main(String[] args) {
StarRulerProxy starProxy = new StarRulerProxy(new ZStar());
Object test = Proxy.newProxyInstance(ZStar.class.getClassLoader(),ZStar.class.getInterfaces(),starProxy);
Singer star = (Singer) test;
star.dance();//我跳舞
System.out.println();
star.sing();//我唱歌
}
}
其中newProxyInstance各个传参含义,首先看源码
其中ClassLoader loader:指定类加载器,我写的例子中很明显是Ztar类的加载器
Class<?>[] interfaces :获取类继承的接口当然也可以用 new Class[]{Singer.class} 代替ZStar.class.getInterfaces() 效果一样。
InvocationHandler h:说明你想要使用哪个规则,如果说你有多个RulerProxy类,你可以指定其中一个。
运行结果:
这是所有方法按统一规则执行的,但如果说我有其中一个方法,不想按这个规则来了,我们可以用if来判断
public class StarRulerProxy implements InvocationHandler {
private Singer singer;//需要实现的接口类
public StarRulerProxy(Singer singer) {
this.singer = singer;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("sing")){
System.out.println("唱歌不要钱");
method.invoke(singer,args);
System.out.println("经纪人不收钱");
}else{
System.out.println("经纪人商量合同");
method.invoke(singer,args);
System.out.println("经纪人收钱");
}
return null;
}
}
运行结果