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) throws IllegalArgumentException
2 Class <?> []interfaces,
3 InvocationHandlerh) throws IllegalArgumentException
参数有点迷惑人,解释下:
ClassLoader 是类加载器,这个参数用来定义代理类,一般使用原对象的即可,也可以为null用上下文解决。
Class<?>[] 接口数组,就是我们需要这个代理能够提供原来的类的什么函数。如果全部则直接 class.getInterfaces() 来解决.
InvocationHandler 调用处理器,这个就是如果你调用代理的方法,那么这个处理器就会被关联过来,处理调用这个函数的整个过程。这个接口只定义了一个方法:
1
public
Objectinvoke(Objectproxy,Methodmethod,
2 Object[]args) throws Throwable;
2 Object[]args) throws Throwable;
参数中 proxy 就是你调用的代理, method 指的是你调用的代理的那个方法, args 是传给该方法的参数。
我们生成某个类的代理步骤,一般需要先考虑我们在调用这个类的函数的时候(之前,或者之后)如何处理某些事情,因此我们首先考虑的就是如何实现 InvocationHandler 这个接口。
让我们做一个实践,做这么一个调用处理器:任何使用此处理器的代理在调用它的任何方法的时候,都打印 被代理的类的类名+“.”+方法名+”(“+参数+”,”+参数+...+”)” 。
步骤1: 定义接口 IUser
1
package
com.cyh.proxy.sample;
2
3 public interface IUser {
4 public StringgetName();
5
6 public void setName(Stringname);
7 }
2
3 public interface IUser {
4 public StringgetName();
5
6 public void setName(Stringname);
7 }
步骤2: 写IUser接口的实现类 User
1
package
com.cyh.proxy.sample.impl;
2
3 import com.cyh.proxy.sample.IUser;
4
5 public class User implements IUser{
6 Stringname;
7
8 public User(Stringname){
9 this .name = name;
10 }
11
12 public StringgetName(){
13 return name;
14 }
15
16 public void setName(Stringname){
17 this .name = name;
18 }
19 }
2
3 import com.cyh.proxy.sample.IUser;
4
5 public class User implements IUser{
6 Stringname;
7
8 public User(Stringname){
9 this .name = name;
10 }
11
12 public StringgetName(){
13 return name;
14 }
15
16 public void setName(Stringname){
17 this .name = name;
18 }
19 }
步骤3: 写 TraceHandler 实现调用处理器 InvocationHandler ,即在 invoke() 方法里我们要打印被 代理的类的类名+“.”+方法名+”(“+参数+”,”+参数+...+”)” 。
1
package
com.cyh.proxy.sample.impl;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5
6 public class TraceHandler implements InvocationHandler{
7 private Objecttarget;
8
9 public TraceHandler(Objecttarget){
10 this .target = target;
11 }
12
13 public Objectinvoke(Objectproxy,Methodmethod,Object[]args)
14 throws Throwable{
15
16 // printimplicitargument
17 System.out.print(target.getClass().getName());
18 // printmethodname
19 System.out.print( " . " + method.getName() + " ( " );
20 // printexplicitarguments
21 if (args != null ){
22 for ( int i = 0 ;i < args.length;i ++ ){
23 System.out.print(args[i]);
24 if (i < args.length - 1 ){
25 System.out.print( " , " );
26 }
27 }
28 }
29 System.out.println( " ) " );
30
31 return method.invoke( this .target,args);
32 }
33 }
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5
6 public class TraceHandler implements InvocationHandler{
7 private Objecttarget;
8
9 public TraceHandler(Objecttarget){
10 this .target = target;
11 }
12
13 public Objectinvoke(Objectproxy,Methodmethod,Object[]args)
14 throws Throwable{
15
16 // printimplicitargument
17 System.out.print(target.getClass().getName());
18 // printmethodname
19 System.out.print( " . " + method.getName() + " ( " );
20 // printexplicitarguments
21 if (args != null ){
22 for ( int i = 0 ;i < args.length;i ++ ){
23 System.out.print(args[i]);
24 if (i < args.length - 1 ){
25 System.out.print( " , " );
26 }
27 }
28 }
29 System.out.println( " ) " );
30
31 return method.invoke( this .target,args);
32 }
33 }
步骤4: 最后,让我们写测试类 ProxyTest
1
package
com.cyh.proxy.sample.test;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Proxy;
5
6 import com.cyh.proxy.sample.IUser;
7 import com.cyh.proxy.sample.impl.TraceHandler;
8 import com.cyh.proxy.sample.impl.User;
9
10 public class ProxyTest{
11 Useruser;
12
13 public ProxyTest(){
14 user = new User( " LaraCroft " );
15
16 ClassLoaderclassLoader = user.getClass().getClassLoader();
17 Class[]interfaces = user.getClass().getInterfaces();
18 InvocationHandlerhandler = new TraceHandler(user);
19 IUserproxy = (IUser)Proxy.newProxyInstance(classLoader,interfaces,
20 handler);
21
22 proxy.setName( " DavidBeckham " );
23 }
24
25 public static void main(String[]args){
26 new ProxyTest();
27 }
28
29 }
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Proxy;
5
6 import com.cyh.proxy.sample.IUser;
7 import com.cyh.proxy.sample.impl.TraceHandler;
8 import com.cyh.proxy.sample.impl.User;
9
10 public class ProxyTest{
11 Useruser;
12
13 public ProxyTest(){
14 user = new User( " LaraCroft " );
15
16 ClassLoaderclassLoader = user.getClass().getClassLoader();
17 Class[]interfaces = user.getClass().getInterfaces();
18 InvocationHandlerhandler = new TraceHandler(user);
19 IUserproxy = (IUser)Proxy.newProxyInstance(classLoader,interfaces,
20 handler);
21
22 proxy.setName( " DavidBeckham " );
23 }
24
25 public static void main(String[]args){
26 new ProxyTest();
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
1
package
com.cyh.proxy.interceptor;
2
3 public interface DynamicProxyFactory{
4 /**
5 *生成动态代理,并且在调用代理执行函数的时候使用拦截器
6 *
7 * @param clazz
8 *需要实现的接口
9 * @param target
10 *实现此接口的类
11 * @param interceptor
12 *拦截器
13 * @return
14 */
15 public < T > TcreateProxy(Ttarget,Interceptorinterceptor);
16 }
2
3 public interface DynamicProxyFactory{
4 /**
5 *生成动态代理,并且在调用代理执行函数的时候使用拦截器
6 *
7 * @param clazz
8 *需要实现的接口
9 * @param target
10 *实现此接口的类
11 * @param interceptor
12 *拦截器
13 * @return
14 */
15 public < T > TcreateProxy(Ttarget,Interceptorinterceptor);
16 }
步骤2: 定义接口 Interceptor
1
package
com.cyh.proxy.interceptor;
2
3 import java.lang.reflect.Method;
4
5 public interface Interceptor{
6 public void before(Methodmethod,Object[]args);
7
8 public void after(Methodmethod,Object[]args);
9
10 public void afterThrowing(Methodmethod,Object[]args,Throwablethrowable);
11
12 public void afterFinally(Methodmethod,Object[]args);
13 }
14
2
3 import java.lang.reflect.Method;
4
5 public interface Interceptor{
6 public void before(Methodmethod,Object[]args);
7
8 public void after(Methodmethod,Object[]args);
9
10 public void afterThrowing(Methodmethod,Object[]args,Throwablethrowable);
11
12 public void afterFinally(Methodmethod,Object[]args);
13 }
14
步骤3: 实现接口 DynamicProxyFactory
1
package
com.cyh.proxy.interceptor.impl;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Proxy;
5
6 import com.cyh.proxy.interceptor.DynamicProxyFactory;
7 import com.cyh.proxy.interceptor.Interceptor;
8
9 public class DynamicProxyFactoryImpl implements DynamicProxyFactory{
10 /**
11 *生成动态代理,并且在调用代理执行函数的时候使用拦截器
12 *
13 * @param target
14 *需要代理的实例
15 * @param interceptor
16 *拦截器实现,就是我们希望代理类执行函数的前后,
17 *抛出异常,finally的时候去做写什么
18 */
19 @Override
20 @SuppressWarnings( " unchecked " )
21 public < T > TcreateProxy(Ttarget,Interceptorinterceptor){
22 // 当前对象的类加载器
23 ClassLoaderclassLoader = target.getClass().getClassLoader();
24 // 获取此对象实现的所有接口
25 Class <?> []interfaces = target.getClass().getInterfaces();
26 // 利用DynamicProxyInvocationHandler类来实现InvocationHandler
27 InvocationHandlerhandler = new DynamicProxyInvocationHandler(target,
28 interceptor);
29
30 return (T)Proxy.newProxyInstance(classLoader,interfaces,handler);
31 }
32 }
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Proxy;
5
6 import com.cyh.proxy.interceptor.DynamicProxyFactory;
7 import com.cyh.proxy.interceptor.Interceptor;
8
9 public class DynamicProxyFactoryImpl implements DynamicProxyFactory{
10 /**
11 *生成动态代理,并且在调用代理执行函数的时候使用拦截器
12 *
13 * @param target
14 *需要代理的实例
15 * @param interceptor
16 *拦截器实现,就是我们希望代理类执行函数的前后,
17 *抛出异常,finally的时候去做写什么
18 */
19 @Override
20 @SuppressWarnings( " unchecked " )
21 public < T > TcreateProxy(Ttarget,Interceptorinterceptor){
22 // 当前对象的类加载器
23 ClassLoaderclassLoader = target.getClass().getClassLoader();
24 // 获取此对象实现的所有接口
25 Class <?> []interfaces = target.getClass().getInterfaces();
26 // 利用DynamicProxyInvocationHandler类来实现InvocationHandler
27 InvocationHandlerhandler = new DynamicProxyInvocationHandler(target,
28 interceptor);
29
30 return (T)Proxy.newProxyInstance(classLoader,interfaces,handler);
31 }
32 }
步骤4: 实现调用处理器
1
package
com.cyh.proxy.interceptor.impl;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5
6 import com.cyh.proxy.interceptor.Interceptor;
7
8 /**
9 *动态代理的调用处理器
10 *
11 * @author chen.yinghua
12 */
13 public class DynamicProxyInvocationHandler implements InvocationHandler{
14 private Objecttarget;
15 private Interceptorinterceptor;
16
17 /**
18 * @param target
19 *需要代理的实例
20 * @param interceptor
21 *拦截器
22 */
23 public DynamicProxyInvocationHandler(Objecttarget,
24 Interceptorinterceptor){
25 this .target = target;
26 this .interceptor = interceptor;
27 }
28
29 /**
30 * @param proxy
31 *所生成的代理对象
32 * @param method
33 *调用的方法示例
34 *@argsargs参数数组
35 *@Override
36 */
37 public Objectinvoke(Objectproxy,Methodmethod,Object[]args)
38 throws Throwable{
39 Objectresult = null ;
40
41 try {
42 // 在执行method之前调用interceptor去做什么事
43 this .interceptor.before(method,args);
44 // 在这里我们调用原始实例的method
45 result = method.invoke( this .target,args);
46 // 在执行method之后调用interceptor去做什么事
47 this .interceptor.after(method,args);
48 } catch (Throwablethrowable){
49 // 在发生异常之后调用interceptor去做什么事
50 this .interceptor.afterThrowing(method,args,throwable);
51 throw throwable;
52 } finally {
53 // 在finally之后调用interceptor去做什么事
54 interceptor.afterFinally(method,args);
55 }
56
57 return result;
58 }
59
60 }
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5
6 import com.cyh.proxy.interceptor.Interceptor;
7
8 /**
9 *动态代理的调用处理器
10 *
11 * @author chen.yinghua
12 */
13 public class DynamicProxyInvocationHandler implements InvocationHandler{
14 private Objecttarget;
15 private Interceptorinterceptor;
16
17 /**
18 * @param target
19 *需要代理的实例
20 * @param interceptor
21 *拦截器
22 */
23 public DynamicProxyInvocationHandler(Objecttarget,
24 Interceptorinterceptor){
25 this .target = target;
26 this .interceptor = interceptor;
27 }
28
29 /**
30 * @param proxy
31 *所生成的代理对象
32 * @param method
33 *调用的方法示例
34 *@argsargs参数数组
35 *@Override
36 */
37 public Objectinvoke(Objectproxy,Methodmethod,Object[]args)
38 throws Throwable{
39 Objectresult = null ;
40
41 try {
42 // 在执行method之前调用interceptor去做什么事
43 this .interceptor.before(method,args);
44 // 在这里我们调用原始实例的method
45 result = method.invoke( this .target,args);
46 // 在执行method之后调用interceptor去做什么事
47 this .interceptor.after(method,args);
48 } catch (Throwablethrowable){
49 // 在发生异常之后调用interceptor去做什么事
50 this .interceptor.afterThrowing(method,args,throwable);
51 throw throwable;
52 } finally {
53 // 在finally之后调用interceptor去做什么事
54 interceptor.afterFinally(method,args);
55 }
56
57 return result;
58 }
59
60 }
好了,目前为止,这个框架算完成了,怎么用呢?
接下来我们完成测试包。
完成测试
步骤1: 首先,给需要代理的类定义一个接口 Service
1
package
com.cyh.proxy.interceptor.test;
2
3 public interface Service{
4 public Stringgreet(Stringname);
5 }
2
3 public interface Service{
4 public Stringgreet(Stringname);
5 }
步骤2: 实现这个接口,编写类 ServiceImpl
1
package
com.cyh.proxy.interceptor.test;
2
3 public class ServiceImpl implements Service{
4 @Override
5 public Stringgreet(Stringname){
6 Stringresult = " Hello, " + name;
7 System.out.println(result);
8 return result;
9 }
10 }
2
3 public class ServiceImpl implements Service{
4 @Override
5 public Stringgreet(Stringname){
6 Stringresult = " Hello, " + name;
7 System.out.println(result);
8 return result;
9 }
10 }
步骤3: 实现拦截器接口Interceptor,编写类 InterceptorImpl
1
package
com.cyh.proxy.interceptor.test;
2
3 import java.lang.reflect.Method;
4
5 import com.cyh.proxy.interceptor.Interceptor;
6
7 public class InterceptorImpl implements Interceptor {
8 @Override
9 public void after(Methodmethod,Object[]args) {
10 System.out.println( " afterinvokingmethod: " + method.getName());
11 }
12
13 @Override
14 public void afterFinally(Methodmethod,Object[]args) {
15 System.out.println( " afterFinallyinvokingmethod: " + method.getName());
16 }
17
18 @Override
19 public void afterThrowing(Methodmethod,Object[]args,
20 Throwablethrowable) {
21 System.out.println( " afterThrowinginvokingmethod: "
22 + method.getName());
23 }
24
25 @Override
26 public void before(Methodmethod,Object[]args) {
27 System.out.println( " beforeinvokingmethod: " + method.getName());
28 }
29 }
2
3 import java.lang.reflect.Method;
4
5 import com.cyh.proxy.interceptor.Interceptor;
6
7 public class InterceptorImpl implements Interceptor {
8 @Override
9 public void after(Methodmethod,Object[]args) {
10 System.out.println( " afterinvokingmethod: " + method.getName());
11 }
12
13 @Override
14 public void afterFinally(Methodmethod,Object[]args) {
15 System.out.println( " afterFinallyinvokingmethod: " + method.getName());
16 }
17
18 @Override
19 public void afterThrowing(Methodmethod,Object[]args,
20 Throwablethrowable) {
21 System.out.println( " afterThrowinginvokingmethod: "
22 + method.getName());
23 }
24
25 @Override
26 public void before(Methodmethod,Object[]args) {
27 System.out.println( " beforeinvokingmethod: " + method.getName());
28 }
29 }
步骤4:编写测试类 TestDynamicProxy
1
package
com.cyh.proxy.interceptor.test;
2
3 import com.cyh.proxy.interceptor.DynamicProxyFactory;
4 import com.cyh.proxy.interceptor.Interceptor;
5 import com.cyh.proxy.interceptor.impl.DynamicProxyFactoryImpl;
6
7 public class TestDynamicProxy{
8 public TestDynamicProxy(){
9 DynamicProxyFactorydynamicProxyFactory = new DynamicProxyFactoryImpl();
10 Interceptorinterceptor = new InterceptorImpl();
11 Serviceservice = new ServiceImpl();
12
13 Serviceproxy = dynamicProxyFactory.createProxy(service,interceptor);
14 // Serviceproxy=DefaultProxyFactory.createProxy(service,
15 // interceptor);
16 proxy.greet( " iwindyforest " );
17 }
18
19 public static void main(String[]args){
20 new TestDynamicProxy();
21 }
22 }
2
3 import com.cyh.proxy.interceptor.DynamicProxyFactory;
4 import com.cyh.proxy.interceptor.Interceptor;
5 import com.cyh.proxy.interceptor.impl.DynamicProxyFactoryImpl;
6
7 public class TestDynamicProxy{
8 public TestDynamicProxy(){
9 DynamicProxyFactorydynamicProxyFactory = new DynamicProxyFactoryImpl();
10 Interceptorinterceptor = new InterceptorImpl();
11 Serviceservice = new ServiceImpl();
12
13 Serviceproxy = dynamicProxyFactory.createProxy(service,interceptor);
14 // Serviceproxy=DefaultProxyFactory.createProxy(service,
15 // interceptor);
16 proxy.greet( " iwindyforest " );
17 }
18
19 public static void main(String[]args){
20 new TestDynamicProxy();
21 }
22 }
好了,整个测试包完成了,让我们运行下看看运行结果:
before invoking method: greet
Hello, iwindyforest
after invoking method: greet
afterFinally invoking method: greet
完善设计
现在,让我们回顾一下:接口 DynamicProxyFactory ,真的需要么?
它只是一个工厂,负责生产代理的,但是我们并没有过多的要求,因此可以说它的实现基本上是不变的。鉴于此,我们在使用 createProxy() 函数的时候,只需要一个 静态方法 就可以了,没有必要再初始化整个类,这样才比较方便么。
因此,我在 com.cyh.proxy.interceptor.impl 包里加了一个默认的工厂 DefaultProxyFactory :
1
package
com.cyh.proxy.interceptor.impl;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Proxy;
5
6 import com.cyh.proxy.interceptor.Interceptor;
7
8 public class DefaultProxyFactory{
9 @SuppressWarnings( " unchecked " )
10 public static < T > TcreateProxy(Ttarget,Interceptorinterceptor){
11 // 当前对象的类加载器
12 ClassLoaderclassLoader = target.getClass().getClassLoader();
13 // 获取此对象实现的所有接口
14 Class <?> []interfaces = target.getClass().getInterfaces();
15 // 利用DynamicProxyInvocationHandler类来实现InvocationHandler
16 InvocationHandlerhandler = new DynamicProxyInvocationHandler(target,
17 interceptor);
18
19 return (T)Proxy.newProxyInstance(classLoader,interfaces,handler);
20 }
21 }
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Proxy;
5
6 import com.cyh.proxy.interceptor.Interceptor;
7
8 public class DefaultProxyFactory{
9 @SuppressWarnings( " unchecked " )
10 public static < T > TcreateProxy(Ttarget,Interceptorinterceptor){
11 // 当前对象的类加载器
12 ClassLoaderclassLoader = target.getClass().getClassLoader();
13 // 获取此对象实现的所有接口
14 Class <?> []interfaces = target.getClass().getInterfaces();
15 // 利用DynamicProxyInvocationHandler类来实现InvocationHandler
16 InvocationHandlerhandler = new DynamicProxyInvocationHandler(target,
17 interceptor);
18
19 return (T)Proxy.newProxyInstance(classLoader,interfaces,handler);
20 }
21 }