其实现在我还没有体会到动态代理和静态代理之间的差异(可能是因为我现在接触动态代理还不是很深,在以后可能才会理解动态代理的好处,读者千万不要看到这段话就认为动态代理和静态代理没差别)。现在唯一让我觉得动态代理有点优势的就是,静态代理的代理主题类中必须实现所有真实主题的方法,如果真实主题里面的方法有10个,代理主题也必须实现这10个方法(代理主题和真实主题实现同一个主题接口)。而动态代理,只用短短的几行代码返回一个代理对象(这里会应用到反射技术,需要注意的是,凡是涉及到反射,被反射的对象必须有一个无参构造函数,否则反射将失败),通过这个代理对象,就可以调用所有真实主题的方法了。
我也看过一篇博文中说道:Spring容器代替工厂 (创建Bean)、Spring AOP代替JDK动态代理 (解耦)。说明动态代理还是很有用的。这也让我对Sping的内部实现有了一个大概的印象。
话不多说了下面给出实现代码;
1 新建一个主题接口
public interface ISinger { /** * 唱歌 */ void sing(); /** * 签合同 */ void signContract(); /** * 演出 */ void performance(); }2 新建一个真实主题类 (歌手类)
public class Singer implements ISinger{ @Override public void sing() { System.out.println("唱歌"); } @Override public void signContract() { System.out.println("签约"); } @Override public void performance() { System.out.println("表演"); } }
3 新建一个代理对象类 并实现InvocationHandler
public class MyInvoke implements InvocationHandler{ Object object; public Object bind(Object object){ this.object = object; return Proxy.newProxyInstance( object.getClass().getClassLoader(), object.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object o = method.invoke(object, args); return o; } }
4 新建一个测试类 当然 Myinvoke并不是专为歌手类创建的,你也可以将一个运动员类对象绑定到MyInvoke的一个代理对象。
public class DynamicProxyTest { public static void main(String[] a){ Singer singer = new Singer(); MyInvoke si = new MyInvoke(); ISinger is = (ISinger) si.bind(singer); is.sing(); is.performance(); } }
输出结果:
唱歌
表演