1、代理模式
首先,在我们想要了解动态代理之前,我们先要了解什么是代理模式,那么什么是代理模式呢?在某些情况下,我们不能直接去调用一个对象,这个时候就需要使用到代理对象,它就相当于是一个中介。比如我们工作特别繁忙,但是这个时候我们又想看房子,就可以通过中介商来实现看房买房。代里模式它是一种设计模式,以后在开发中的某些情况下会使用到。
2、动态代理
在学习动态代理之前,我们首先需要重新回顾一下关于反射的知识。
Class<?> cls = Class.forName("com.alibaba.Student"); //首先获取字节码文件对象
Constructor c = cls.getConstructor(Integer.class, String.class);//获取构造器,通过构造new实例
Object obj = c.newInstance(1, "Lauren");// 创建一个实例对象
Method method = cls.getMethod("msg", String.class); // 通过字节码对象拿到指定的方法。
method.invoke(obj, "Hello"); // 第一个参数表示字节码对象的类,第二个参数表示方法形参值。
// 有一个返回值Object,如果方法是有返回值的就是相应的返回结果,否则是Null
//这里需要重新温习一下反射的知识。
也就是说method.invoke(obj, “Hello” )方法,是对被反射的类里的方法的调用,我们刚刚是获取了Student的Class对象,也就是说,是对Student类里方法的一个调用,第一个参数需要填写的是Student的一个实例对象,第二个参数是方法里需要传进去的参数。
|
|
|
接下来我们来讲一下如何生成一个动态代理对象以及里面的参数是什么。
public Object getProxy() {
//当前类的类加载器,通过当前类的类加载器对代理类进行加载,加载到内存
ClassLoader loader = this.getClass().getClassLoader();
//获取目标类的父接口
Class<?>[] interfaces = calc.getClass().getInterfaces();
//需不需要额外添加功能
return Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//让代理类,可以调用目标类的方法。
Object result = method.invoke(calc, args);
return result;
}
});
}
首先呐,我们先创建一个名叫MyProxy的类,里面写一个叫getProxy()的方法,在Proxy这个类里有一个名叫newProxyInstance的静态方法,我们通过它可以返回一个代理对象,这个方法里面有三个参数,分别是什么呢?我们一起来看一下。
1、第一个参数是类加载器,我们可以使用当前类的类加载器,让它将代理类加载至内存。
2、第二个参数是父接口,这里需要填写到目标对象的父接口,因为Proxy要根据这个目标类的父接口,在底层实现一个代理类。
3、第三个参数是InvocationHandler,这是一个接口,我们可以使用匿名内部类来进行一个实现,它的作用就在于让代理类去调用目标类里的实现方法,并且还可以自身对原本的目标类里的方法进行一个增强。(简单来说就是让代理类去调用目标类的实现方法,并且还可以在此基础之上添加额外功能,例如日志、验证等)
|
|
|
|
3、疑惑解答
其实动态代理很好理解,就是有些情况下我们不能直接对目标类进行一个访问,这个时候就需要中间商,也就是代理对象,我们通过Proxy里的newProxyInstance,指定目标对象的父类接口,它就会根据这个接口里的抽象方法,隐含的在底层实现一个代理类,这个时候肯定有人会问,那实现了代理类,里面重写的方法咋办?,,其实代理类并没有重写接口里的那些方法,是直接通过反射对目标对象里的方法进行的调用,在此基础之上,还可以添加一些额外的非业务逻辑代码,例如日志信息、验证啊啥的,下面是我话的一张草图,希望有助于大家理解。