根据上篇静态代理,现在写一下动态代理
静态代理的使用,是一对一的一个代理类对应一个被代理类,如果被代理的类多的话,代码会很繁杂。动态代理可以解决这一个问题,动态代理是对代理类进行统一整理,采用一个通用的代理类,代理所有的需要代理的别代理类的使用。
代码实例:
interface Human{
String say();
void fly();
}
//被代理类
class SuperMan implements Human{
@Override
public String say() {
return "我是超人!我怕谁!";
}
@Override
public void fly() {
System.out.println("I believe I can fly!");
}
}
class HumanUtil{
public void method1(){
System.out.println("==========通用的操作一=================");
}
public void method2(){
System.out.println("==========通用的操作二=================");
}
}
/*
- 要想实现动态代理类对象的功能,需要解决两个问题:
- ①如何根据加载到内存中的被代理类对象,动态的去创建代理类的对象
- ②如何通过代理类的对象调用接口中声明的方法时,实现对被代理类对象同名方法的调用
*/
class MyInvocationHandler implements InvocationHandler{
private Object obj;//被代理类的对象
public void bind(Object obj){//实例化被代理类的对象
this.obj = obj;
}
//解决上述说明的问题②
//当通过代理类的对象调用接口中的方法a时,就会调用如下的InvocationHandler中的invoke()
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
HumanUtil humanUtil = new HumanUtil();
humanUtil.method1();
//method:单行注释中的方法a
Object returnVal = method.invoke(obj, args);
humanUtil.method2();
return returnVal;
}
}
class ProxyFactory{
//调用此方法,返回一个代理类的对象
public static Object getProxyInstance(Object obj){//形参obj:被代理类的对象
MyInvocationHandler handler = new MyInvocationHandler();
handler.bind(obj);
//解决上述说明的问题①
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(), handler);
}
}
public class ProxyTest {
public static void main(String[] args) {
SuperMan man = new SuperMan();//被代理类对象
Object proxyObj = ProxyFactory.getProxyInstance(man);//proxyObj:代理类对象
Human human = (Human) proxyObj;
Object returnValue = human.say();//代理类对象调用接口中声明的方法
System.out.println(returnValue);
human.fly();
System.out.println("****************");
NikeClothFactory nike = new NikeClothFactory();
ClothFactory proxy = (ClothFactory) ProxyFactory.getProxyInstance(nike);
proxy.produceCloth();//代理类对象调用接口中声明的方法
}
}