在路上

 找回密码
 立即注册
在路上 站点首页 学习 查看内容

详解java动态代理模式

2016-8-16 12:48| 发布者: zhangjf| 查看: 687| 评论: 0

摘要: 本文针对java动态代理进行知识点整理,具体内容如下 一. JAVA的动态代理(比较官方说法)   代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处 理消息、过滤消息、 ...

本文针对java动态代理进行知识点整理,具体内容如下

一. JAVA的动态代理(比较官方说法)
  代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处 理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。  代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的 对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提  供特定的服务。
  按照代理的创建时期,代理类可以分为两种。
  静态代理:程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
  动态代理:在程序运行时,运用反射机制动态创建而成。

二. 动态代理实现

  java.lang.reflect.Proxy,
  Proxy 提供用于创建动态代理类和实例的静态方法.
  newProxyInstance()
  返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。

2.1. Dao接口(提供模拟数据访问层接口)

  1. package javaproxy;
  2. /*
  3. * 定义一个数据访问层接口
  4. */
  5. public interface Dao {
  6. //模拟数据保存
  7. public void save();
  8. }
复制代码

2.2. DaoImpl类实现类

  1. package javaproxy;
  2. public class DaoImpl implements Dao{
  3. @Override
  4. public void save() {
  5. System.out.println("执行一个保存方法。。。。。。。。。。。。");
  6. }
  7. }
复制代码

2.3. 代理处理类

  1. package javaproxy;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. public class DaoHandler implements InvocationHandler{
  5. private Object obj;
  6. public DaoHandler(Object obj) {
  7. this.obj=obj;
  8. }
  9. @Override
  10. public Object invoke(Object proxy, Method method, Object[] args)
  11. throws Throwable {
  12. System.out.println("do something before method");//这里模拟AOP的前置方法
  13. Object ret = method.invoke(this.obj, args);
  14. System.out.println("do something after method");//这里模拟AOP的后置方法
  15. return ret;
  16. }
  17. }
复制代码

2.4. client调用

  1. package javaproxy;
  2. import java.lang.reflect.Proxy;
  3. public class Client {
  4. public static void main(String[] args) {
  5. // 元对象(被代理对象)
  6. DaoImpl daoImpl = new DaoImpl();
  7. // 业务代理类
  8. DaoHandler daoHandler=new DaoHandler(daoImpl);
  9. Dao dao=(Dao) Proxy.newProxyInstance(daoImpl
  10. .getClass().getClassLoader(), daoImpl.getClass()
  11. .getInterfaces(), daoHandler);
  12. dao.save();
  13. }
  14. }
复制代码

2. 5. 结果

3. 模拟Mybatis中的代理实现

3.1. MapperProxy类

  1. package javaproxy;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. public class MapperProxy implements InvocationHandler {
  6. @SuppressWarnings("unchecked")
  7. /*
  8. * 这里通过静态方法得到实现类的对象
  9. *
  10. * @param:接口
  11. *
  12. * @param:用sqlsession执行方法
  13. *
  14. * @return: 返回代理对像
  15. */
  16. public static <T> T newMapperProxy(Class<T> mapperInterface,
  17. Object sqlSession) {
  18. ClassLoader classLoader = mapperInterface.getClassLoader();
  19. Class<?>[] interfaces = new Class[] { mapperInterface };
  20. MapperProxy proxy = new MapperProxy();
  21. return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy);
  22. }
  23. /*
  24. * (non-Javadoc)
  25. *
  26. * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
  27. * java.lang.reflect.Method, java.lang.Object[])
  28. *
  29. * @param:代理对象
  30. *
  31. * @param:方法通过方法名字找到对应的方法
  32. *
  33. * @param:通过方法传入对象找到对应的传递参数映射
  34. *
  35. * @return:返回执行后的参数对象
  36. */
  37. public Object invoke(Object proxy, Method method, Object[] args)
  38. throws Throwable {
  39. // 这里通过方法名字以及参数通过解析对应的mapper来执行对应的操作
  40. System.out.println("在这里执行实际方法");
  41. return null;
  42. }
  43. }
复制代码

3.2. Client

  1. package javaproxy;
  2. import java.lang.reflect.Proxy;
  3. public class Client {
  4. public static void main(String[] args) {
  5. Dao dao=MapperProxy.newMapperProxy(Dao.class, null);
  6. dao.save();
  7. }
  8. }
复制代码

3.3. 结果

以上是使用JDK动态代理的例子,希望对大家学习java程序设计有所帮助。

最新评论

小黑屋|在路上 ( 蜀ICP备15035742号-1 

;

GMT+8, 2025-5-6 15:43

Copyright 2015-2025 djqfx

返回顶部