动态代理案例代码注解


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


//动态代理的使用,体会反射是动态语言的关键
interface Subject {
void action();
int action1();
}




// 被代理类
class RealSubject implements Subject {
public void action() {
System.out.println("我是被代理类,记得要执行我哦!么么~~");
}


@Override
public int action1() {
System.out.println("我是被代理类211111,记得要执行我哦!11么么~~");
return 12222;

}
}


class MyInvocationHandler implements InvocationHandler {
Object obj;// 实现了接口的被代理类的对象的声明
public void f(){

}

// ①给被代理的对象实例化②返回一个代理类的对象
public Object blind(Object obj) {
this.obj = obj;

return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),this);       //getInterfaces() 代理类要实现的接口  , //obj.getClass().getClassLoader() 获得类加载器

 //最后返回代理类MyInvocationHandler的 对象,这个对象获取了obj的接口和类加载器,这样就动态的创建代理类的对象 
}
//当通过代理类的对象发起对被重写的方法的调用时,都会转换为对如下的invoke方法的调用
@Override
public Object invoke(Object proxy, Method method, Object[] args)//在代理(handler)实例上处理方法调用并返回结果
throws Throwable {
//method方法的返回值时returnVal

Object returnVal = method.invoke(obj, args);//反射调用obj的方法,相较于静态代理,

                                                                       // 这里就可以不用知道被代理类的方法。实现动态调用

return returnVal;
}
}


public class TestProxy {
public static void main(String[] args) {
//1.被代理类的对象
RealSubject real = new RealSubject();
//2.创建一个实现了InvacationHandler接口的类的对象
MyInvocationHandler handler = new MyInvocationHandler();

//3.调用blind()方法,动态的返回一个对象,这个对象是实现了real所在类实现的接口(Subject)的代理类

//(MyInvocationHandler)的对象。简而言之,返回的是代理类的对象,而这个代理类通过反射获得了被代理类的接口和方法  //然后通过Subject sub强转使这些方法能被调用。

Object obj = handler.blind(real);//这是多态的体现
Subject sub = (Subject)obj;//此时sub就是代理类的对象 当调用sub的方法时,就自动通过invoke()方法反射到被代理里的方法。//通过接口向下转型从而使obj能调用重写接口的方法
// 类里MyInvocationHandler的 方法,比如 f()并不能被调用
sub.action();// 也说明了动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象。
System.out.println(sub.action1())  ;//转到对InvacationHandler接口的实现类的invoke()方法的调用



}
}

猜你喜欢

转载自blog.csdn.net/qiuzhongweiwei/article/details/80918188