反射与动态代理简直是影视圈的神马组合
Java可以在运行的时候知道对象的信息,这主要体现在Java的两个功能,RTTI和反射。
反射
上篇文章我们讲了RTTI的一些特性,它可以确定运行时的对象类型,这个类是在编译的时候是确定的,这样才能通过编译后的Class文件来加载类对象。当我们在编译时无法获取类信息的时候,就可以考虑使用反射,既然本地没有Class文件,可能就是通过网络获取Class文件,这时候我们就可以使用反射来获取类信息。
JDK中有个java.lang.reflect反射包,里面定义了反射用到的一些类,
代理
反射往往与动态代理相结合使用,所谓代理就是自己由于各种各样的原因不好抛头露面,有一个代理类来帮它完成一件事情,代理类往往在真正方法执行的前后添加逻辑。 下面我们举个代理模式使用的例子来说明一些
静态代理
定义一个接口:
interface Interface {
void doSomething();
}
定义真正的对象:
class RealObject implements Interface {
public void doSomething() {
System.out.println("简单输出");
}
}
定义代理类:
class SimpleProxy implements Interface {
private Interface proxied;
public SimpleProxy(Interface proxied) {
this.proxied = proxied;
}
public void doSomething() {
System.out.println("使用代理类");
proxied.doSomething();
}
}
使用:
new SimpleProxy(new RealObject()).doSomething();
这样我们看一下代码,,输出结果如下会先输出使用代理类
,然后是简单输出
这是静态代理的实现,代理类需要我们定义,而动态代理就不一样了。
动态代理
动态代理可以动态创建代理并动态调用需要代理的方法。
定义动态代理类,这里我们使用实现InvocationHandler接口来,并重写他的invoke()方法
动态代理类:
class DynamicProxyHandler implements InvocationHandler {
private Object proxied;
public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理类: " + proxy.getClass() + ", 方法: " + method + ", 参数: " + args);
if(args != null)
for(Object arg : args)
System.out.println(" " + arg);
return method.invoke(proxied, args);
}
}
动态代理类的这一个invoke()方法的重写就够用了,当接口定义其他方法的时候,静态代理类需要同时实现接口的其他方法,而动态代理类就不需要了,这就是它的优势所在。
使用:
Interface proxy = (Interface)Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[]{ Interface.class },
new DynamicProxyHandler(new RealObject()));
proxy.doSomething();
运行结果:代理类:class $Proxy0, 方法:public abstract void Interface.doSomething(),参数: null
这里定义的动态代理类和静态代理类差不多,但比静态代理类稍微复杂一点。
我们使用Proxy.newProxyInstance()方法来创建动态代理对象,Method的invoke()方法调用被代理的对象的相应的方法,参数也可以携带。
总结
这篇文章我们讲了反射和代理的内容,往往他们两个结合起来使用,代理又分为静态代理和动态代理,动态代理相比静态代理更加灵活,减少代理类方法的编写,这也是我们生产中或者源码中经常用到的代理模式。动态代理的实现我们这里是使用了实现InvocationHandler接口的JDK代理方式,除此之外还可以使用CGlib代理。
❤️ 感谢大家
如果你觉得这篇内容对你挺有有帮助的话: