经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
java JDK动态代理
来源:cnblogs  作者:惊柯  时间:2018/10/20 15:37:47  对本文有异议

本篇随笔是对java动态代理中的JDK代理方式的具体实现。

首先需要定义一个接口,为其定义了两个方法:

  1. public interface UserService {
  2. public void add();
  3. public void delete();
  4. }

 

然后需要一个实现这个接口的实现类:
  1. public class UserServiceImpl implements UserService {
  2. @Override
  3. public void add() {
  4.    //添加一些操作
  5. System.out.println("UserServiceImpl中的add()方法被执行了");
  6. }
  7. @Override
  8. public void delete() {
  9.    //添加一些操作
  10. System.out.println("UserServiceImpl中的delete()方法被执行了");
  11. }
  12. }
 
此时如果要在调用add()方法和delete()方法时先输入一句话:System.out.println("动态代理开启");
第一种方式:直接在方法体内部输出,此时就会出现一个问题:“硬编码”,对以后的扩展不方便。
第二种方式:使用java中动态代理机制,主要有JDK和CGLIB两种方式。本文主要使用JDK的方式。
 
此时,创建一个动态代理类:
  1. public class DynaProxyInvocationHandler implements InvocationHandler {
  2. // 定义被代理对象,该对象必须实现了至少一个接口
  3. private Object target;
  4. // 定义代理方法,该方法代理后的返回值类型是被代理对象原类型
  5. public Object Proxy(Object target) {
  6. this.target=target;
  7. return Proxy.newProxyInstance(
  8. this.target.getClass().getClassLoader(),
  9. this.target.getClass().getInterfaces(),
  10. this);
  11. }
  12. /**
  13. * 当一个类实现了InvocationHandler接口后,必须实现invoke方法
  14. * 而这个方法就是增强被代理对象的方法
  15. */
  16. @Override
  17. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  18. System.out.println("动态代理开启");
  19. return method.invoke(this.target, args);
  20. }
  21. }

 

其中的Proxy是JDK为我们提供的动态代理对象,该对象提供了newProxyInstance()来进行初始化,参数说明如下:
第一个参数:被代理对象的类装载器
第二个参数:被代理对象所实现的接口
第三个参数:实现InvocationHandler接口的类

而其中的invoke方法中有着三个参数:
第一个参数:代理对象,一般在动态代理中不会使用。
第二个参数:被代理对象所执行的方法
第三个参数:被代理对象所执行的方法的参数列表
 
此时,可以建立一个测试类查看一下效果:
  1. public class DynaProxtTest {
  2. public static void main(String[] args) {
  3. // 创建被代理对象
  4. UserService userService = new UserServiceImpl();
  5. // 对象UserService进行代理
  6. UserService us = (UserService)new DynaProxyInvocationHandler().Proxy(userService);
  7. //调用代理后的方法
  8. us.add();
  9.    System.out.println("=============");
  10. us.delete();
  11. }
  12. }

 

此时控制台的输出会是:
  1. 动态代理开启
  2. UserServiceImpl中的add()方法被执行了
  3. =============
  4. 动态代理开启
  5. UserServiceImpl中的delete()方法被执行了

 

此时,如果要对代理方法进行限制,可以使用以下方法:

  1. @Override
  2. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  3. Object result = null;
  4. if(method.getName().contains("add")) {
  5. System.out.println("动态代理开启");
  6. result = method.invoke(this.target, args);
  7. }else {
  8. result = method.invoke(this.target, args);
  9. }
  10. return result;
  11. }

 

此时控制台的输出会是:
  1. 动态代理开启
  2. UserServiceImpl中的add()方法被执行了
  3. =============
  1. UserServiceImpl中的delete()方法被执行了
  1.  

 

因为Spring的AOP就是通过动态代理的机制实现的,所以还是需要好好的理解动态代理的机制的。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号