JDK 动态代理是通过 JDK 中的 java.lang.reflect.Proxy 类实现的。下面通过具体的案例演示 JDK 动态代理的使用。
1. 创建项目
在 MyEclipse 中创建一个名称为 springDemo03 的 Web 项目,将 Spring 支持和依赖的 JAR 包复制到 Web 项目的 WEB-INF/lib 目录中,并发布到类路径下。
2. 创建接口 CustomerDao
在项目的 src 目录下创建一个名为 com.mengma.dao 的包,在该包下创建一个 CustomerDao 接口,编辑后如下所示。
package com.mengma.dao;
public interface CustomerDao {
public void add(); // 添加
public void update(); // 修改
public void delete(); // 删除
public void find(); // 查询
}
3. 创建实现类 CustomerDaoImpl
在 com.mengma.dao 包下创建 CustomerDao 接口的实现类 CustomerDaoImpl,并实现该接口中的所有方法,如下所示。
package com.mengma.dao;
public class CustomerDaoImpl implements CustomerDao {
@Override
public void add() {
System.out.println("添加客户...");
}
@Override
public void update() {
System.out.println("修改客户...");
}
@Override
public void delete() {
System.out.println("删除客户...");
}
@Override
public void find() {
System.out.println("修改客户...");
}
}
4. 创建切面类 MyAspect
在 src 目录下,创建一个名为 com.mengma.jdk 的包,在该包下创建一个切面类 MyAspect,编辑后如下所示。
package com.mengma.jdk;
public class MyAspect {
public void myBefore() {
System.out.println("方法执行之前");
}
public void myAfter() {
System.out.println("方法执行之后");
}
}
上述代码中,在切面中定义了两个增强的方法,分别为 myBefore() 方法和 myAfter() 方法,用于对目标类(CustomerDaoImpl)进行增强。
5. 创建代理类 MyBeanFactory
在 com.mengma.jdk 包下创建一个名为 MyBeanFactory 的类,在该类中使用 java.lang.reflect.Proxy 实现 JDK 动态代理,如下所示。
package com.mengma.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.mengma.dao.CustomerDao;
import com.mengma.dao.CustomerDaoImpl;
public class MyBeanFactory {
public static CustomerDao getBean() {
// 准备目标类
final CustomerDao customerDao = new CustomerDaoImpl();
// 创建切面类实例
final MyAspect myAspect = new MyAspect();
// 使用代理类,进行增强
return (CustomerDao) Proxy.newProxyInstance(
MyBeanFactory.class.getClassLoader(),
new Class[] { CustomerDao.class }, new InvocationHandler() {
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
myAspect.myBefore(); // 前增强
Object obj = method.invoke(customerDao, args);
myAspect.myAfter(); // 后增强
return obj;
}
});
}
}
上述代码中,定义了一个静态的 getBean() 方法,这里模拟 Spring 框架的 IoC 思想,通过调用 getBean() 方法创建实例,第 14 行代码创建了 customerDao 实例。
第 16 行代码创建的切面类实例用于调用切面类中相应的方法;第 18~26 行就是使用代理类对创建的实例 customerDao 中的方法进行增强的代码,其中 Proxy 的 newProxyInstance() 方法的第一个参数是当前类的类加载器,第二参数是所创建实例的实现类的接口,第三个参数就是需要增强的方法。
在目标类方法执行的前后,分别执行切面类中的 myBefore() 方法和 myAfter() 方法。
6. 创建测试类 JDKProxyTest
在 com.mengma.jdk 包下创建一个名为 JDKProxyTest 的测试类,如下所示。
package com.mengma.jdk;
import org.junit.Test;
import com.mengma.dao.CustomerDao;
public class JDKProxyTest {
@Test
public void test() {
// 从工厂获得指定的内容(相当于spring获得,但此内容时代理对象)
CustomerDao customerDao = MyBeanFactory.getBean();
// 执行方法
customerDao.add();
customerDao.update();
customerDao.delete();
customerDao.find();
}
}
上述代码中,在调用 getBean() 方法时,获取的是 CustomerDao 类的代理对象,然后调用了该对象中的方法。
7. 运行项目并查看结果
使用 JUnit 测试运行 test() 方法,运行成功后,控制台的输出结果

吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring JDK动态代理的更多相关文章

  1. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:继承的应用

    class Array{ // 表示数组 private int temp[] ; // 整型数组 private int foot ; // 定义添加位置 public Array(int len) ...

  2. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:匿名内部类

    interface A{ public void printInfo() ; // } class B implements A{ // 实现接口 public void printInfo(){ S ...

  3. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:包装类

    public class WrapperDemo01{ public static void main(String args[]){ int x = 30 ; // 基本数据类型 Integer i ...

  4. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:Object类

    class Demo{ // 定义Demo类,实际上就是继承了Object类 }; public class ObjectDemo01{ public static void main(String ...

  5. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:宠物商店实例分析

    interface Pet{ // 定义宠物接口 public String getName() ; public String getColor() ; public int getAge() ; ...

  6. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:抽象类与接口的应用

    abstract class A{ // 定义抽象类A public abstract void print() ; // 定义抽象方法print() }; class B extends A { / ...

  7. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:instanceof关键字

    class A{ // 定义类A public void fun1(){ // 定义fun1()方法 System.out.println("A --> public void fun ...

  8. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:对象的多态性

    class A{ // 定义类A public void fun1(){ // 定义fun1()方法 System.out.println("A --> public void fun ...

  9. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:接口的基本实现

    interface A{ // 定义接口A public static final String AUTHOR = "李兴华" ; // 全局常量 public abstract ...

  10. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:final关键字

    final class A{ // 使用final定义类,不能有子类 }; class B extends A{ // 错误,不能被继承 }; class A{ public final void p ...

随机推荐

  1. jmeter之http请求用csv读取中文乱码

    jmeter3.2版本中CSV Data Set Config从本地读取静态文件的时候,遇到中文乱码的解决方式如下: CSV Data Set Config设置 http请求数据显示乱码 把txt文档 ...

  2. 设备树DTS 学习:4-编写实战

    背景 讲完设备树的有关概念以及语法以后,我们接下来就让 我们的驱动 使用 设备树. ref : <内核学习笔记14:内核设备树学习>.<u-boot对设备树的支持> 测试代码 ...

  3. Wpa_supplicant 调试故障原因分析

    背景 在使用Wpa_supplicant 工具调试Linux的wifi的时候,发现有一些问题.特此记录一下.有些问题是遇到的并已经有了解决方法,一些问题比较发杂,只能作为思路. 问题以及解决办法 1. ...

  4. 使用 Doxygen 生成文档 (以FFmpeg 4.1.1 为例)

    背景 在查找 ffmpeg 文档的时候,发现其文档是根据 Doxygen 生成的. 为了学习方便,这里以 生成 ffmpeg 4.1 文档 为例. 注:为了兼顾 arm 与 host ,本人选择了同时 ...

  5. java执行操作系统脚本

    http://www.cnblogs.com/bencakes/p/6139477.html 以前只是知道Runtime.getRuntime().exec(command);这种用法,但是有时候命令 ...

  6. mitmproxy 配置

    pip install mitmproxy Man In The Middle 原理 mitmproxy工程工具包,主要包含了3个组件 功能一致,交互界面不同 mitmproxy:命令行界面,wind ...

  7. Mysql数据库的简单介绍与入门

    Mysql数据库的简单介绍与入门 前言 一.下载与安装 1.下载 官网下载MYSQL5.7.21版本,链接地址https://www.mysql.com/downloads/.下载流程图如下: 找到M ...

  8. python中excel表格的读写

    #!usr/bin/env python #-*- coding:utf-8 -*- import xlrd import xlwt from xlutils.copy import copy imp ...

  9. C++面试常见问题——07容器和迭代器

    容器和迭代器 vector.list.deque #include<iostream> #include<vector> #include<deque> #incl ...

  10. 对jsp中的js进行调试的方法

    在js中 输入debugger 就可以了