Spring JDK动态代理

Myth丶恋晨 2023-07-13 10:56 204阅读 0赞

JDK 动态代理是通过 JDK 中的 java.lang.reflect.Proxy 类实现的。下面通过具体的案例演示 JDK 动态代理的使用。

1. 创建项目
在 MyEclipse 中创建一个名称为 spring 的 Web 项目,将 Spring 支持和依赖的 JAR 包复制到 Web 项目的 WEB-INF/lib 目录中,并发布到类路径下。

2. 创建接口 CustomerDao
在项目的 src 目录下创建一个名为 com.mengma.dao 的包,在该包下创建一个 CustomerDao 接口,编辑后如下所示。

  1. package com.mengma.dao;
  2. public interface CustomerDao {
  3. public void add(); // 添加
  4. public void update(); // 修改
  5. public void delete(); // 删除
  6. public void find(); // 查询
  7. }

3. 创建实现类 CustomerDaoImpl
在 com.mengma.dao 包下创建 CustomerDao 接口的实现类 CustomerDaoImpl,并实现该接口中的所有方法,如下所示。
package com.mengma.dao;

  1. public class CustomerDaoImpl implements CustomerDao {
  2. @Override
  3. public void add() {
  4. System.out.println("添加客户...");
  5. }
  6. @Override
  7. public void update() {
  8. System.out.println("修改客户...");
  9. }
  10. @Override
  11. public void delete() {
  12. System.out.println("删除客户...");
  13. }
  14. @Override
  15. public void find() {
  16. System.out.println("修改客户...");
  17. }
  18. }

4. 创建切面类 MyAspect
在 src 目录下,创建一个名为 com.mengma.jdk 的包,在该包下创建一个切面类 MyAspect,编辑后如下所示。

  1. package com.mengma.jdk;
  2. public class MyAspect {
  3. public void myBefore() {
  4. System.out.println("方法执行之前");
  5. }
  6. public void myAfter() {
  7. System.out.println("方法执行之后");
  8. }
  9. }

上述代码中,在切面中定义了两个增强的方法,分别为 myBefore() 方法和 myAfter() 方法,用于对目标类(CustomerDaoImpl)进行增强。

5. 创建代理类 MyBeanFactory
在 com.mengma.jdk 包下创建一个名为 MyBeanFactory 的类,在该类中使用 java.lang.reflect.Proxy 实现 JDK 动态代理,如下所示。

  1. package com.mengma.jdk;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. import com.mengma.dao.CustomerDao;
  6. import com.mengma.dao.CustomerDaoImpl;
  7. public class MyBeanFactory {
  8. public static CustomerDao getBean() {
  9. // 准备目标类
  10. final CustomerDao customerDao = new CustomerDaoImpl();
  11. // 创建切面类实例
  12. final MyAspect myAspect = new MyAspect();
  13. // 使用代理类,进行增强
  14. return (CustomerDao) Proxy.newProxyInstance(
  15. MyBeanFactory.class.getClassLoader(),
  16. new Class[] { CustomerDao.class }, new InvocationHandler() {
  17. public Object invoke(Object proxy, Method method,
  18. Object[] args) throws Throwable {
  19. myAspect.myBefore(); // 前增强
  20. Object obj = method.invoke(customerDao, args);
  21. myAspect.myAfter(); // 后增强
  22. return obj;
  23. }
  24. });
  25. }
  26. }

上述代码中,定义了一个静态的 getBean() 方法,这里模拟 Spring 框架的 IoC 思想,通过调用 getBean() 方法创建实例,第 14 行代码创建了 customerDao 实例。

在目标类方法执行的前后,分别执行切面类中的 myBefore() 方法和 myAfter() 方法。

6. 创建测试类 JDKProxyTest
在 com.mengma.jdk 包下创建一个名为 JDKProxyTest 的测试类,如下所示。

  1. package com.mengma.jdk;
  2. import org.junit.Test;
  3. import com.mengma.dao.CustomerDao;
  4. public class JDKProxyTest {
  5. @Test
  6. public void test() {
  7. // 从工厂获得指定的内容(相当于spring获得,但此内容时代理对象)
  8. CustomerDao customerDao = MyBeanFactory.getBean();
  9. // 执行方法
  10. customerDao.add();
  11. customerDao.update();
  12. customerDao.delete();
  13. customerDao.find();
  14. }
  15. }

上述代码中,在调用 getBean() 方法时,获取的是 CustomerDao 类的代理对象,然后调用了该对象中的方法。

7. 运行项目并查看结果
使用 JUnit 测试运行 test() 方法,运行成功后,控制台的输出结果如下图所示。
在这里插入图片描述
从输出结果中可以看出,在调用目标类的方法前后,成功调用了增强的代码,由此说明,JDK 动态代理已经实现。

发表评论

表情:
评论列表 (有 0 条评论,204人围观)

还没有评论,来说两句吧...

相关阅读

    相关 9_Spring_JDK动态代理

    代理模式 是通过代理对象访问目标对象,这样可以在目标对象基础上增强额外的功能,如添加权限,访问控制和审计等功能。 房产中介代替业主卖房 ![b9c7284a183c4a6