AOP技术是spring框架的一个重要特征。通过该特性能够在函数运行之前,之后,或者异常处理的时候执行我们需要的一些操作。
下面我们就是需要抛开AOP,Spring这样成型的框架不用,而仅仅使用java反射机制中的Proxy,InvocationHandler来实现类似Spring框架的拦截器的效果。
动态代理DynamicProxy
首先,在设计这个拦截器框架之前,我们需要明白java中动态代理是什么?我想如果早就清楚请直接跳过,如果需要了解,那我想你手边最好有一个javadoc的电子书。
Java.lang.reflect.Proxy是反射包的成员之一。具体说明请查javadoc。
用法就是比如有一个对象,我们需要在调用它提供的方法之前,干点别的什么,就不能直接调用它,而是生成一个它的代理,这个代理有这个对象所提供的所有接口方法,我们通过直接调用代理的这些方法,来实现:函数既能像原来对象的那样工作,又能在函数运行过程前后加入我们自己的处理。
这个类有个非常重要的函数用来实现某个类的代理:
参数有点迷惑人,解释下:
ClassLoader 是类加载器,这个参数用来定义代理类,一般使用原对象的即可,也可以为null用上下文解决。
Class<?>[] 接口数组,就是我们需要这个代理能够提供原来的类的什么函数。如果全部则直接class.getInterfaces()来解决.
InvocationHandler 调用处理器,这个就是如果你调用代理的方法,那么这个处理器就会被关联过来,处理调用这个函数的整个过程。这个接口只定义了一个方法:
参数中proxy就是你调用的代理,method指的是你调用的代理的那个方法,args是传给该方法的参数。
我们生成某个类的代理步骤,一般需要先考虑我们在调用这个类的函数的时候(之前,或者之后)如何处理某些事情,因此我们首先考虑的就是如何实现InvocationHandler这个接口。
让我们做一个实践,做这么一个调用处理器:任何使用此处理器的代理在调用它的任何方法的时候,都打印被代理的类的类名+“.”+方法名+”(“+参数+”,”+参数+...+”)”。
步骤1: 定义接口IUser
步骤2: 写IUser接口的实现类User
步骤3: 写TraceHandler实现调用处理器InvocationHandler,即在invoke()方法里我们要打印被代理的类的类名+“.”+方法名+”(“+参数+”,”+参数+...+”)”。
步骤4: 最后,让我们写测试类ProxyTest
好了,所有代码写好了,运行一下,测试结果是:
com.cyh.proxy.impl.User.setName(David Beckham)
讲一下运行原理:
首先我们初始化了user对象,user.name = = “LaraCroft”;
然后创建了user对象的代理proxy。
注意这里:Proxy.newProxyInstance()函数的返回值使用接口IUser转型的,你或许会想到
用User来做强制类型转换,但是会抛出下面的异常
Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to com.cyh.proxy.impl.User
因为:代理类是实现了User类的所有接口,但是它的类型是$Proxy0,不是User。
最后,我们调用代理的setName()方法:
proxy.setName("David Beckham");
代理在执行此方法的时候,就好触发调用处理器 TraceHandler,并执行 TraceHandler的invoke()方法,然后就会打印:
com.cyh.proxy.impl.User.setName(David Beckham)
拦截器框架的实现
好了,关于代理的知识我们讲完了,我们可以考虑如何实现这个拦截器的框架,所谓拦截器就是在函数的运行前后定制自己的处理行为,也就是通过实现InvocationHandler达到的。
设计思路
我们来理清一下思路,在使用一个拦截器的时候?什么是不变的,什么是变化的?
不变的:
每次都要创建代理
拦截的时间:函数执行之前,之后,异常处理的时候
变化的:
每次代理的对象不同
拦截器每次拦截到执行时的操作不同
好了,废话少说,看类图:

图中:
DynamicProxyFactory 和它的实现类,是一个工厂,用来创建代理
Interceptor 这个接口用来定义拦截器的拦截处理行为配合DynamicProxyInvocationHandler达到拦截效果
DynamicProxyInvocationHandler 调用处理器的实现,它有两个成员,一个是Object target指的是被代理的类,另一个是Interceptor interceptor就是在invoke()方法执行target的函数之前后,异常处理时,调用interceptor的实现来达到拦截,并处理的效果。
代码实现
步骤1: 定义接口DynamicProxyFactory
步骤2: 定义接口Interceptor
步骤3: 实现接口DynamicProxyFactory
步骤4: 实现调用处理器
好了,目前为止,这个框架算完成了,怎么用呢?
接下来我们完成测试包。
完成测试
步骤1: 首先,给需要代理的类定义一个接口Service
步骤2: 实现这个接口,编写类ServiceImpl
步骤3: 实现拦截器接口Interceptor,编写类InterceptorImpl
步骤4:编写测试类TestDynamicProxy
好了,整个测试包完成了,让我们运行下看看运行结果:
before invoking method: greet
Hello, iwindyforest
after invoking method: greet
afterFinally invoking method: greet
完善设计
现在,让我们回顾一下:接口DynamicProxyFactory,真的需要么?
它只是一个工厂,负责生产代理的,但是我们并没有过多的要求,因此可以说它的实现基本上是不变的。鉴于此,我们在使用createProxy()函数的时候,只需要一个静态方法就可以了,没有必要再初始化整个类,这样才比较方便么。
因此,我在com.cyh.proxy.interceptor.impl包里加了一个默认的工厂DefaultProxyFactory:
下面我们就是需要抛开AOP,Spring这样成型的框架不用,而仅仅使用java反射机制中的Proxy,InvocationHandler来实现类似Spring框架的拦截器的效果。
动态代理DynamicProxy
首先,在设计这个拦截器框架之前,我们需要明白java中动态代理是什么?我想如果早就清楚请直接跳过,如果需要了解,那我想你手边最好有一个javadoc的电子书。
Java.lang.reflect.Proxy是反射包的成员之一。具体说明请查javadoc。
用法就是比如有一个对象,我们需要在调用它提供的方法之前,干点别的什么,就不能直接调用它,而是生成一个它的代理,这个代理有这个对象所提供的所有接口方法,我们通过直接调用代理的这些方法,来实现:函数既能像原来对象的那样工作,又能在函数运行过程前后加入我们自己的处理。
这个类有个非常重要的函数用来实现某个类的代理:
1
Objectjava.lang.reflect.Proxy.newProxyInstance(ClassLoaderloader,
2
Class<?>[]interfaces,
3
InvocationHandlerh)throwsIllegalArgumentException

2

3

参数有点迷惑人,解释下:
ClassLoader 是类加载器,这个参数用来定义代理类,一般使用原对象的即可,也可以为null用上下文解决。
Class<?>[] 接口数组,就是我们需要这个代理能够提供原来的类的什么函数。如果全部则直接class.getInterfaces()来解决.
InvocationHandler 调用处理器,这个就是如果你调用代理的方法,那么这个处理器就会被关联过来,处理调用这个函数的整个过程。这个接口只定义了一个方法:
1
publicObjectinvoke(Objectproxy,Methodmethod,
2
Object[]args)throwsThrowable;

2

参数中proxy就是你调用的代理,method指的是你调用的代理的那个方法,args是传给该方法的参数。
我们生成某个类的代理步骤,一般需要先考虑我们在调用这个类的函数的时候(之前,或者之后)如何处理某些事情,因此我们首先考虑的就是如何实现InvocationHandler这个接口。
让我们做一个实践,做这么一个调用处理器:任何使用此处理器的代理在调用它的任何方法的时候,都打印被代理的类的类名+“.”+方法名+”(“+参数+”,”+参数+...+”)”。
步骤1: 定义接口IUser
1
packagecom.cyh.proxy.sample;
2
3
publicinterfaceIUser
{
4
publicStringgetName();
5
6
publicvoidsetName(Stringname);
7
}

2

3



4

5

6

7

步骤2: 写IUser接口的实现类User
1packagecom.cyh.proxy.sample.impl;
2
3importcom.cyh.proxy.sample.IUser;
4
5publicclassUserimplementsIUser{
6Stringname;
7
8publicUser(Stringname){
9this.name=name;
10}
11
12publicStringgetName(){
13returnname;
14}
15
16publicvoidsetName(Stringname){
17this.name=name;
18}
19}
2
3importcom.cyh.proxy.sample.IUser;
4
5publicclassUserimplementsIUser{
6Stringname;
7
8publicUser(Stringname){
9this.name=name;
10}
11
12publicStringgetName(){
13returnname;
14}
15
16publicvoidsetName(Stringname){
17this.name=name;
18}
19}
步骤3: 写TraceHandler实现调用处理器InvocationHandler,即在invoke()方法里我们要打印被代理的类的类名+“.”+方法名+”(“+参数+”,”+参数+...+”)”。
1packagecom.cyh.proxy.sample.impl;
2
3importjava.lang.reflect.InvocationHandler;
4importjava.lang.reflect.Method;
5
6publicclassTraceHandlerimplementsInvocationHandler{
7privateObjecttarget;
8
9publicTraceHandler(Objecttarget){
10this.target=target;
11}
12
13publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)
14throwsThrowable{
15
16//printimplicitargument
17System.out.print(target.getClass().getName());
18//printmethodname
19System.out.print("."+method.getName()+"(");
20//printexplicitarguments
21if(args!=null){
22for(inti=0;i<args.length;i++){
23System.out.print(args[i]);
24if(i<args.length-1){
25System.out.print(",");
26}
27}
28}
29System.out.println(")");
30
31returnmethod.invoke(this.target,args);
32}
33}
2
3importjava.lang.reflect.InvocationHandler;
4importjava.lang.reflect.Method;
5
6publicclassTraceHandlerimplementsInvocationHandler{
7privateObjecttarget;
8
9publicTraceHandler(Objecttarget){
10this.target=target;
11}
12
13publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)
14throwsThrowable{
15
16//printimplicitargument
17System.out.print(target.getClass().getName());
18//printmethodname
19System.out.print("."+method.getName()+"(");
20//printexplicitarguments
21if(args!=null){
22for(inti=0;i<args.length;i++){
23System.out.print(args[i]);
24if(i<args.length-1){
25System.out.print(",");
26}
27}
28}
29System.out.println(")");
30
31returnmethod.invoke(this.target,args);
32}
33}
步骤4: 最后,让我们写测试类ProxyTest
1packagecom.cyh.proxy.sample.test;
2
3importjava.lang.reflect.InvocationHandler;
4importjava.lang.reflect.Proxy;
5
6importcom.cyh.proxy.sample.IUser;
7importcom.cyh.proxy.sample.impl.TraceHandler;
8importcom.cyh.proxy.sample.impl.User;
9
10publicclassProxyTest{
11Useruser;
12
13publicProxyTest(){
14user=newUser("LaraCroft");
15
16ClassLoaderclassLoader=user.getClass().getClassLoader();
17Class[]interfaces=user.getClass().getInterfaces();
18InvocationHandlerhandler=newTraceHandler(user);
19IUserproxy=(IUser)Proxy.newProxyInstance(classLoader,interfaces,
20handler);
21
22proxy.setName("DavidBeckham");
23}
24
25publicstaticvoidmain(String[]args){
26newProxyTest();
27}
28
29}
2
3importjava.lang.reflect.InvocationHandler;
4importjava.lang.reflect.Proxy;
5
6importcom.cyh.proxy.sample.IUser;
7importcom.cyh.proxy.sample.impl.TraceHandler;
8importcom.cyh.proxy.sample.impl.User;
9
10publicclassProxyTest{
11Useruser;
12
13publicProxyTest(){
14user=newUser("LaraCroft");
15
16ClassLoaderclassLoader=user.getClass().getClassLoader();
17Class[]interfaces=user.getClass().getInterfaces();
18InvocationHandlerhandler=newTraceHandler(user);
19IUserproxy=(IUser)Proxy.newProxyInstance(classLoader,interfaces,
20handler);
21
22proxy.setName("DavidBeckham");
23}
24
25publicstaticvoidmain(String[]args){
26newProxyTest();
27}
28
29}
好了,所有代码写好了,运行一下,测试结果是:
com.cyh.proxy.impl.User.setName(David Beckham)
讲一下运行原理:
首先我们初始化了user对象,user.name = = “LaraCroft”;
然后创建了user对象的代理proxy。
注意这里:Proxy.newProxyInstance()函数的返回值使用接口IUser转型的,你或许会想到
用User来做强制类型转换,但是会抛出下面的异常
Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to com.cyh.proxy.impl.User
因为:代理类是实现了User类的所有接口,但是它的类型是$Proxy0,不是User。
最后,我们调用代理的setName()方法:
proxy.setName("David Beckham");
代理在执行此方法的时候,就好触发调用处理器 TraceHandler,并执行 TraceHandler的invoke()方法,然后就会打印:
com.cyh.proxy.impl.User.setName(David Beckham)
拦截器框架的实现
好了,关于代理的知识我们讲完了,我们可以考虑如何实现这个拦截器的框架,所谓拦截器就是在函数的运行前后定制自己的处理行为,也就是通过实现InvocationHandler达到的。
设计思路
我们来理清一下思路,在使用一个拦截器的时候?什么是不变的,什么是变化的?
不变的:
每次都要创建代理
拦截的时间:函数执行之前,之后,异常处理的时候
变化的:
每次代理的对象不同
拦截器每次拦截到执行时的操作不同
好了,废话少说,看类图:

图中:
DynamicProxyFactory 和它的实现类,是一个工厂,用来创建代理
Interceptor 这个接口用来定义拦截器的拦截处理行为配合DynamicProxyInvocationHandler达到拦截效果
DynamicProxyInvocationHandler 调用处理器的实现,它有两个成员,一个是Object target指的是被代理的类,另一个是Interceptor interceptor就是在invoke()方法执行target的函数之前后,异常处理时,调用interceptor的实现来达到拦截,并处理的效果。
代码实现
步骤1: 定义接口DynamicProxyFactory
1packagecom.cyh.proxy.interceptor;
2
3publicinterfaceDynamicProxyFactory{
4/**
5*生成动态代理,并且在调用代理执行函数的时候使用拦截器
6*
7*@paramclazz
8*需要实现的接口
9*@paramtarget
10*实现此接口的类
11*@paraminterceptor
12*拦截器
13*@return
14*/
15public<T>TcreateProxy(Ttarget,Interceptorinterceptor);
16}
2
3publicinterfaceDynamicProxyFactory{
4/**
5*生成动态代理,并且在调用代理执行函数的时候使用拦截器
6*
7*@paramclazz
8*需要实现的接口
9*@paramtarget
10*实现此接口的类
11*@paraminterceptor
12*拦截器
13*@return
14*/
15public<T>TcreateProxy(Ttarget,Interceptorinterceptor);
16}
步骤2: 定义接口Interceptor
1packagecom.cyh.proxy.interceptor;
2
3importjava.lang.reflect.Method;
4
5publicinterfaceInterceptor{
6publicvoidbefore(Methodmethod,Object[]args);
7
8publicvoidafter(Methodmethod,Object[]args);
9
10publicvoidafterThrowing(Methodmethod,Object[]args,Throwablethrowable);
11
12publicvoidafterFinally(Methodmethod,Object[]args);
13}
14
2
3importjava.lang.reflect.Method;
4
5publicinterfaceInterceptor{
6publicvoidbefore(Methodmethod,Object[]args);
7
8publicvoidafter(Methodmethod,Object[]args);
9
10publicvoidafterThrowing(Methodmethod,Object[]args,Throwablethrowable);
11
12publicvoidafterFinally(Methodmethod,Object[]args);
13}
14
步骤3: 实现接口DynamicProxyFactory
1packagecom.cyh.proxy.interceptor.impl;
2
3importjava.lang.reflect.InvocationHandler;
4importjava.lang.reflect.Proxy;
5
6importcom.cyh.proxy.interceptor.DynamicProxyFactory;
7importcom.cyh.proxy.interceptor.Interceptor;
8
9publicclassDynamicProxyFactoryImplimplementsDynamicProxyFactory{
10/**
11*生成动态代理,并且在调用代理执行函数的时候使用拦截器
12*
13*@paramtarget
14*需要代理的实例
15*@paraminterceptor
16*拦截器实现,就是我们希望代理类执行函数的前后,
17*抛出异常,finally的时候去做写什么
18*/
19@Override
20@SuppressWarnings("unchecked")
21public<T>TcreateProxy(Ttarget,Interceptorinterceptor){
22//当前对象的类加载器
23ClassLoaderclassLoader=target.getClass().getClassLoader();
24//获取此对象实现的所有接口
25Class<?>[]interfaces=target.getClass().getInterfaces();
26//利用DynamicProxyInvocationHandler类来实现InvocationHandler
27InvocationHandlerhandler=newDynamicProxyInvocationHandler(target,
28interceptor);
29
30return(T)Proxy.newProxyInstance(classLoader,interfaces,handler);
31}
32}
2
3importjava.lang.reflect.InvocationHandler;
4importjava.lang.reflect.Proxy;
5
6importcom.cyh.proxy.interceptor.DynamicProxyFactory;
7importcom.cyh.proxy.interceptor.Interceptor;
8
9publicclassDynamicProxyFactoryImplimplementsDynamicProxyFactory{
10/**
11*生成动态代理,并且在调用代理执行函数的时候使用拦截器
12*
13*@paramtarget
14*需要代理的实例
15*@paraminterceptor
16*拦截器实现,就是我们希望代理类执行函数的前后,
17*抛出异常,finally的时候去做写什么
18*/
19@Override
20@SuppressWarnings("unchecked")
21public<T>TcreateProxy(Ttarget,Interceptorinterceptor){
22//当前对象的类加载器
23ClassLoaderclassLoader=target.getClass().getClassLoader();
24//获取此对象实现的所有接口
25Class<?>[]interfaces=target.getClass().getInterfaces();
26//利用DynamicProxyInvocationHandler类来实现InvocationHandler
27InvocationHandlerhandler=newDynamicProxyInvocationHandler(target,
28interceptor);
29
30return(T)Proxy.newProxyInstance(classLoader,interfaces,handler);
31}
32}
步骤4: 实现调用处理器
1packagecom.cyh.proxy.interceptor.impl;
2
3importjava.lang.reflect.InvocationHandler;
4importjava.lang.reflect.Method;
5
6importcom.cyh.proxy.interceptor.Interceptor;
7
8/**
9*动态代理的调用处理器
10*
11*@authorchen.yinghua
12*/
13publicclassDynamicProxyInvocationHandlerimplementsInvocationHandler{
14privateObjecttarget;
15privateInterceptorinterceptor;
16
17/**
18*@paramtarget
19*需要代理的实例
20*@paraminterceptor
21*拦截器
22*/
23publicDynamicProxyInvocationHandler(Objecttarget,
24Interceptorinterceptor){
25this.target=target;
26this.interceptor=interceptor;
27}
28
29/**
30*@paramproxy
31*所生成的代理对象
32*@parammethod
33*调用的方法示例
34*@argsargs参数数组
35*@Override
36*/
37publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)
38throwsThrowable{
39Objectresult=null;
40
41try{
42//在执行method之前调用interceptor去做什么事
43this.interceptor.before(method,args);
44//在这里我们调用原始实例的method
45result=method.invoke(this.target,args);
46//在执行method之后调用interceptor去做什么事
47this.interceptor.after(method,args);
48}catch(Throwablethrowable){
49//在发生异常之后调用interceptor去做什么事
50this.interceptor.afterThrowing(method,args,throwable);
51throwthrowable;
52}finally{
53//在finally之后调用interceptor去做什么事
54interceptor.afterFinally(method,args);
55}
56
57returnresult;
58}
59
60}
2
3importjava.lang.reflect.InvocationHandler;
4importjava.lang.reflect.Method;
5
6importcom.cyh.proxy.interceptor.Interceptor;
7
8/**
9*动态代理的调用处理器
10*
11*@authorchen.yinghua
12*/
13publicclassDynamicProxyInvocationHandlerimplementsInvocationHandler{
14privateObjecttarget;
15privateInterceptorinterceptor;
16
17/**
18*@paramtarget
19*需要代理的实例
20*@paraminterceptor
21*拦截器
22*/
23publicDynamicProxyInvocationHandler(Objecttarget,
24Interceptorinterceptor){
25this.target=target;
26this.interceptor=interceptor;
27}
28
29/**
30*@paramproxy
31*所生成的代理对象
32*@parammethod
33*调用的方法示例
34*@argsargs参数数组
35*@Override
36*/
37publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)
38throwsThrowable{
39Objectresult=null;
40
41try{
42//在执行method之前调用interceptor去做什么事
43this.interceptor.before(method,args);
44//在这里我们调用原始实例的method
45result=method.invoke(this.target,args);
46//在执行method之后调用interceptor去做什么事
47this.interceptor.after(method,args);
48}catch(Throwablethrowable){
49//在发生异常之后调用interceptor去做什么事
50this.interceptor.afterThrowing(method,args,throwable);
51throwthrowable;
52}finally{
53//在finally之后调用interceptor去做什么事
54interceptor.afterFinally(method,args);
55}
56
57returnresult;
58}
59
60}
好了,目前为止,这个框架算完成了,怎么用呢?
接下来我们完成测试包。
完成测试
步骤1: 首先,给需要代理的类定义一个接口Service
1packagecom.cyh.proxy.interceptor.test;
2
3publicinterfaceService{
4publicStringgreet(Stringname);
5}
2
3publicinterfaceService{
4publicStringgreet(Stringname);
5}
步骤2: 实现这个接口,编写类ServiceImpl
1packagecom.cyh.proxy.interceptor.test;
2
3publicclassServiceImplimplementsService{
4@Override
5publicStringgreet(Stringname){
6Stringresult="Hello,"+name;
7System.out.println(result);
8returnresult;
9}
10}
2
3publicclassServiceImplimplementsService{
4@Override
5publicStringgreet(Stringname){
6Stringresult="Hello,"+name;
7System.out.println(result);
8returnresult;
9}
10}
步骤3: 实现拦截器接口Interceptor,编写类InterceptorImpl
1
packagecom.cyh.proxy.interceptor.test;
2
3
importjava.lang.reflect.Method;
4
5
importcom.cyh.proxy.interceptor.Interceptor;
6
7
publicclassInterceptorImplimplementsInterceptor
{
8
@Override
9
publicvoidafter(Methodmethod,Object[]args)
{
10
System.out.println("afterinvokingmethod:"+method.getName());
11
}
12
13
@Override
14
publicvoidafterFinally(Methodmethod,Object[]args)
{
15
System.out.println("afterFinallyinvokingmethod:"+method.getName());
16
}
17
18
@Override
19
publicvoidafterThrowing(Methodmethod,Object[]args,
20
Throwablethrowable)
{
21
System.out.println("afterThrowinginvokingmethod:"
22
+method.getName());
23
}
24
25
@Override
26
publicvoidbefore(Methodmethod,Object[]args)
{
27
System.out.println("beforeinvokingmethod:"+method.getName());
28
}
29
}

2

3

4

5

6

7



8

9



10

11

12

13

14



15

16

17

18

19

20



21

22

23

24

25

26



27

28

29

步骤4:编写测试类TestDynamicProxy
1packagecom.cyh.proxy.interceptor.test;
2
3importcom.cyh.proxy.interceptor.DynamicProxyFactory;
4importcom.cyh.proxy.interceptor.Interceptor;
5importcom.cyh.proxy.interceptor.impl.DynamicProxyFactoryImpl;
6
7publicclassTestDynamicProxy{
8publicTestDynamicProxy(){
9DynamicProxyFactorydynamicProxyFactory=newDynamicProxyFactoryImpl();
10Interceptorinterceptor=newInterceptorImpl();
11Serviceservice=newServiceImpl();
12
13Serviceproxy=dynamicProxyFactory.createProxy(service,interceptor);
14//Serviceproxy=DefaultProxyFactory.createProxy(service,
15//interceptor);
16proxy.greet("iwindyforest");
17}
18
19publicstaticvoidmain(String[]args){
20newTestDynamicProxy();
21}
22}
2
3importcom.cyh.proxy.interceptor.DynamicProxyFactory;
4importcom.cyh.proxy.interceptor.Interceptor;
5importcom.cyh.proxy.interceptor.impl.DynamicProxyFactoryImpl;
6
7publicclassTestDynamicProxy{
8publicTestDynamicProxy(){
9DynamicProxyFactorydynamicProxyFactory=newDynamicProxyFactoryImpl();
10Interceptorinterceptor=newInterceptorImpl();
11Serviceservice=newServiceImpl();
12
13Serviceproxy=dynamicProxyFactory.createProxy(service,interceptor);
14//Serviceproxy=DefaultProxyFactory.createProxy(service,
15//interceptor);
16proxy.greet("iwindyforest");
17}
18
19publicstaticvoidmain(String[]args){
20newTestDynamicProxy();
21}
22}
好了,整个测试包完成了,让我们运行下看看运行结果:
before invoking method: greet
Hello, iwindyforest
after invoking method: greet
afterFinally invoking method: greet
完善设计
现在,让我们回顾一下:接口DynamicProxyFactory,真的需要么?
它只是一个工厂,负责生产代理的,但是我们并没有过多的要求,因此可以说它的实现基本上是不变的。鉴于此,我们在使用createProxy()函数的时候,只需要一个静态方法就可以了,没有必要再初始化整个类,这样才比较方便么。
因此,我在com.cyh.proxy.interceptor.impl包里加了一个默认的工厂DefaultProxyFactory:
1packagecom.cyh.proxy.interceptor.impl;
2
3importjava.lang.reflect.InvocationHandler;
4importjava.lang.reflect.Proxy;
5
6importcom.cyh.proxy.interceptor.Interceptor;
7
8publicclassDefaultProxyFactory{
9@SuppressWarnings("unchecked")
10publicstatic<T>TcreateProxy(Ttarget,Interceptorinterceptor){
11//当前对象的类加载器
12ClassLoaderclassLoader=target.getClass().getClassLoader();
13//获取此对象实现的所有接口
14Class<?>[]interfaces=target.getClass().getInterfaces();
15//利用DynamicProxyInvocationHandler类来实现InvocationHandler
16InvocationHandlerhandler=newDynamicProxyInvocationHandler(target,
17interceptor);
18
19return(T)Proxy.newProxyInstance(classLoader,interfaces,handler);
20}
21}
2
3importjava.lang.reflect.InvocationHandler;
4importjava.lang.reflect.Proxy;
5
6importcom.cyh.proxy.interceptor.Interceptor;
7
8publicclassDefaultProxyFactory{
9@SuppressWarnings("unchecked")
10publicstatic<T>TcreateProxy(Ttarget,Interceptorinterceptor){
11//当前对象的类加载器
12ClassLoaderclassLoader=target.getClass().getClassLoader();
13//获取此对象实现的所有接口
14Class<?>[]interfaces=target.getClass().getInterfaces();
15//利用DynamicProxyInvocationHandler类来实现InvocationHandler
16InvocationHandlerhandler=newDynamicProxyInvocationHandler(target,
17interceptor);
18
19return(T)Proxy.newProxyInstance(classLoader,interfaces,handler);
20}
21}