什么是动态代理?
java动态代理机制
- Q1:什么叫做动态代理机制?
- Q2:动态代理机制有什么好处?
- Q3:什么地方用到动态代理?
动态代理的源码在java.lang.reflect这个包里,应该是Proxy类。里面有提供两个静态方法:
1.Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface)
用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”,
用来冒充真实的对象。
2.Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类),
它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(…)方法,所以在
invoke方法中,我们可以做很多事情。
“动态”是针对静态编码而言的,可以是编译器、类装载器和运行期。
引一个大大的例子来说下自己的理解:比如有有一个接口A,里面有方法sayHello(),print()方法。然后一个B类(AIml类)来实现
具体实现A接口,然后再写一个代理类,伪装成B类,代理类里面通过动态的实现B类的方法(其实就是通过反射实现的B类方法),
然后外面的请求发过来之后,都是通过代理类来处理,方便集中处理一系列的方便的集成权限控制,异常处理,事务控制,
性能统计等等(这里感谢 方老师 对我指点)
然后下面是一个网上大大对动态代理的画的图,大家参考一下很明了的关系图。
A接口
1 2 3 4
| public interface A { public void sayHello(String to); public void print(String p); }
|
B类(实现A接口)
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class AImpl implements A{ @Override public void sayHello(String to) { System.out.println("Hello:"+to); } @Override public void print(String p) { System.out.println("print:"+p); } }
|
C类(代理类,伪装成B类)
1 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 30 31
| import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class Handler implements InvocationHandler{ private Object obj; public Handler(Object obj){ this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { doBefore(); Object result = method.invoke(obj, args); doAfter(); return result; } private void doAfter() { System.out.println("after..."); } private void doBefore() { System.out.println("before..."); } }
|
测试类:D类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import java.lang.reflect.Proxy; public class ProxyTester { public static void main(String[] args) { A impl = new AImpl(); Handler handler = new Handler(impl); A hello = (A) Proxy.newProxyInstance(impl.getClass().getClassLoader(), impl.getClass().getInterfaces(), handler); hello.print("All the test"); hello.sayHello("SunnyZhu"); } }
|
测试结果如下:
1 2 3 4 5 6
| before... print:All the test after... before... Hello:zhushiqing after...
|
自此代码就实现了,在hello(A类)调用的动态方法都是集中交给代理类来处理了。方便在代理类集中处理一些事情,before 干点啥,after干点啥。
最后回答下三个Questions
A1:一种用于转发请求,进行特殊处理的机制,这里的动态是针对静态编码而言的,可以是编译器、类装载器和运行期。
A2:方便的集成权限控制,异常处理,事务控制,性能统计等等
A3:很多地方,web层的controller,biz层的service,都会使用动态代理,目的在于实现aop,
学习了java动态代理,与诸君共勉!