Dynamic Proxy(动态代理)

时间:2021-08-03 15:18:40

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

输出结果:

唱歌
表演