小村村长

导航

动态代理的个人理解笔记

JDK动态代理

jdk动态代理是代理模式的一种实现方式,只能代理接口interface

原因:代理对象要对被代理对象属性功能进行增强。
二者之间必须要有共同的方法(方法名一致)
代理对象通过重写 @override 被代理对象的方法来对被代理对象进行增强
总结:动态代理对象,代理的就是接口的实现类,重写实现类的方法(也是接口的方法)来对实现类进行增强。

使用步骤:

1.新建一个接口Subject
2.为这个接口创建一个实现类 SubjectImpl
3.创建java.lang.reflect.InvocationHandler接口的实现类,对接口SubjectImpl方法进行增强
4.创建动态代理对象,并对结果验证测试

演示:

1.创建一个接口

/**
 * 创建一个接口
 * 包含共同的方法doSomething
 */
public interface Subject {
    void doSomething();
}

 2.创建这个接口的实现类

 1 package com.Proxy;
 2 
 3 /**
 4  * @Version V1.0
 5  * @Author: leo
 6  * @Date: 2019-12-15 15:42
 7  * @Description:创建接口的真实实现类
 8  */
 9 public class SubjectImpl implements Subject {
10 
11     @Override
12     public void doSomething() {
13         System.out.println("我是接口的实现类SubjectImpl,重写实现了接口的doSomething()方法");
14 
15     }
16 }

3.创建java.lang.reflect.InvocationHandler接口的实现类,对接口SubjectImpl方法进行增强

 
 1 package com.Proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 /**
 7  * @Version V1.0
 8  * @Author: leo
 9  * @Date: 2019-12-15 17:53
10  * @Description:InvocationHandler接口实现类,
11  * 通过重写invoHandler接口中的invoke方法对代理对象(接口Subject的实现类SubjectImpl的对象)
12  * 实现的接口(Subject接口)中的方法(doSomething())进行增强;
13  */
14 public class InvocationHandlerImpl implements InvocationHandler {
15 
16     //method方法执行时候需要 SubjectImpl的实现类,这里对象给一个最大的类对象
17     private Object object;
18     public InvocationHandlerImpl(Object object) {
19         this.object = object;
20     }
21 
22     /**
23      * @param proxy  Subject接口的实现类SubjectImpl的动态代理对象。
24      * @param method 需要增强的方法对象可以通过反射获得。
25      *               method = SubjectImpl.class.getDeclaredMethod();
26      * @param args   上述增强的方法的参数们(方法可能有多个参数,所以是一个参数数组)
27      * @return invoke
28      * @throws Throwable
29      */
30     @Override
31     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
32 
33         method.setAccessible(true);
34         System.out.println("SubjectImpl的doSomething()方法增强前");
35         
36         //这里通过反射,object为执行方法的对象,这里是被代理对象SubjectImpl的实现类对象,args是参数
37         Object invoke = method.invoke(object, args);
38         System.out.println("SubjectImpl的doSomething()方法增强后");
39         return invoke;
40     }
41 }

 

4.创建动态代理类对象来执行增强后相同的方法SubjectImpl中的方法

 
 1 package com.Proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 
 7 /**
 8  * @Version V1.0
 9  * @Author: leo
10  * @Date: 2019-12-15 17:32
11  * @Description:创建接口Subject实现类SUbjectImpl的动态代理对象。
12  */
13 public class SubjectProxy {
14 
15     public static void main(String[] args) {
16 
17         InvocationHandlerImpl invocationHandler = new InvocationHandlerImpl( new SubjectImpl());
18 
19 /**
20  * 创建动态代理对象
21  * 创建代理对象方法newProxyInstance(loader,interfaces,h)
22  * 参数1:类加载器,作用:将代理类加载到JVM方法区中去
23  * 参数2:表示代理类和被代理类的共同父接口们,属于Class类型。
24  *        问题1:为什么这里需要父接口?
25  *               因为被代理类和代理类要有共同的方法,只有这里将父接口传递到底层,
26  *               那么生成的代理类对象才可以调用共同方法
27  *        问题2:这里怎么提供?
28  *               Class<?>[] interfaces = {Subject.class};
29  *               根据反射机制,使用Class类中的方法可以获取共同父接口们。
30  *               Class<?>[] getInterfaces() 确定此对象所表示的类或接口实现的接口。
31  *               object.getClass().getInterfaces();
32  *
33  * 参数3:h:invocationHandle实现类对象,对接口和实现类的共有方法进行增强。
34  */
35         Subject proxyInstance = (Subject) Proxy.newProxyInstance(SubjectProxy.class.getClassLoader(), new Class[]{Subject.class}, invocationHandler
36         );
37         System.out.println("创建了动态代理对象,下面是动态代理对方法增强的效果");
38         proxyInstance.doSomething();
39     }
40 }

 

执行结果如下:

创建了动态代理对象,下面是动态代理对方法增强的效果
SubjectImpl的doSomething()方法增强前
我是接口的实现类SubjectImpl,重写实现了接口的doSomething()方法
SubjectImpl的doSomething()方法增强后

posted on 2019-12-15 19:20  小村村长  阅读(77)  评论(0编辑  收藏  举报