动态代理
动态代理涉及的内核思想比较深,现在暂时无法理解其在java虚拟机中的具体实行过程但是可以做大概的理解。有动态代理就有静态代理,其实动态代理的产生就是为了解决静态代理所产生的大量实例类。在静态代理中代理类和结果类实现了共同的接口,我们通过代理类来访问结果类。用户可以在代理类的方法中进行自定义可以在进行结果类之前和之后增加自己的操作。最形象的例子就是火车站的售票点和街道代售点了。它们的功能是一样的代理其实就是一个中介功能。随着类的增加会使得系统中存在着大量的实例类,不利于维护。
动态代理的思想其实很简单,你需要使用代理类增加的条件就创建一个代理实例类,使用完后销毁该实例。直接调用结果类的方法则不产生代理类直接调用结果类的方法。通过一个InvocationHandler接口来实现。代理类实现InvocationHandler接口和自己代理的接口方法产生一个动态代理类。在调用代理接口的方法前InvocationHandler中的方法invoke都会进行拦截,如果需要代理类则创建一个代理类。如果只是执行结果类的方法则直接执行虚拟机事先加载的结果类方法。这样可以提高效率并且不会产生大量实例类。
public interface Human {
void sing(float money);
void dance(float money);
}
public class SpringBrother implements Human {
public void sing(float money) {
System.out.println("美女唱歌的费用"+money);
}
public void dance(float money) {
System.out.println("美女跳舞的费用"+money);
}
}
public class Client {
public static void main(String[] args) {
final Human sb = new SpringBrother();
Human proxyMan = (Human)Proxy.newProxyInstance(sb.getClass().getClassLoader(),
sb.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
if("sing".equals(method.getName())){
float money = (Float)args[0];
if(money>10000){
method.invoke(sb, money/2);
}
}
if("dance".equals(method.getName())){
float money = (Float)args[0];
if(money>20000){
method.invoke(sb, money/2);
}
}
return null;
}
}
);
proxyMan.sing(20000);
proxyMan.dance(100000);
}
}