其实现在我还没有体会到动态代理和静态代理之间的差异(可能是因为我现在接触动态代理还不是很深,在以后可能才会理解动态代理的好处,读者千万不要看到这段话就认为动态代理和静态代理没差别)。现在唯一让我觉得动态代理有点优势的就是,静态代理的代理主题类中必须实现所有真实主题的方法,如果真实主题里面的方法有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();
}
}
输出结果:
唱歌
表演