AOP日志框架实现

JDK动态代理实现日志框架

首先,在项目包com.ay.test 下创建业务接口类BusinessClassService,具体代码如下:

BusinessC lassService 业务接口类可以理解为日常开发业务创建的接口类, 接口中有一个简 单的方法doSomeThing 。然后,开发业务类的实现类BusinessClassServiceImpl,具体代码如下:

实现类BusinessClassServicelmpl 实现了BusinessClassServ ice 接口, 并实现了doSomeThing 方法,在方法中打印“ do something ......” 。接着,开发日志接口类My Logger , 具体代码如下:

• savelntoMethodTime : 记录进入方法的时间。 • saveOutMethodTime : 记录退出方法的时间。 接口类MyLogger 开发完成之后,用MyLoggerlmpl 类实现它, 具体代码如下:

MyLoggerlmpl 类实现接口MyLogger , 并实现savelntoMethodTime 和saveOutMethodTime 方法,在方法内部打印进入/退出方法的时间。 最后, 实现最重要的类MyLoggerHandler , 具体代码如下:

• lnvocationHandler : 该接口中仅定义了一个方法: public Object invoke(Object obj, Method method, Object[] args) , 在使用时,第一个参数obj 一般是指代理类, method是 被代理的方法, args为该方法的参数数组。这个抽象方法在代理类中动态实现。 所有的代码开发完成之后,开发测试类MyLoggerTest 进行测试, 具体代码如下:

• Proxy . newProxylnstance :该类即为动态代理类, static Object newProxylnstance (ClassLoader loader, Class[] interfaces, JnvocationHandler h),返回代理类的一个实例,返 回后的代理类可以当作被代理类使用。在Proxy.new Proxy Instance方法中,共有以下三 个参数: • Classloader loader: targetObject.getClass().getClassLoader()目标对象通过getClass 方法获取类的所有信息后,调用getClassLoader()方法来获取类加载器。获取类力口载 器后,可以通过这个类型的加载器,在程序运行时,将生成的代理类力口载到JVM即 Java虚拟机中,以使运行时需要。 •Class[] interfaces: targetObject.getClass().getinterfaces()获取被代理类的所有接口信 息,以便于生成的代理类可以具有代理类接口中的所有方法。 • lnvocationHandler h : 使用动态代理是为了更好地扩展, 比如在方法之前做什么操 作,之后做什么操作,这个时候这些公共的操作可以统一交给代理类去做。此时需 要调用实现了InvocationHandler 类的一个回调方法。

运行测试类的ma in 方法,便可以在Intellij IDEA 控制台查看打印信息,具体信息如下:

以上就是利用动态代理模式实现简单的日志框架, 具体的结构如图

这里总结一下JDK 动态代理的一般实现步骤: ( l )创建一个实现InvocationHandler 接口的类MyLoggerHandler,它必须实现invoke 方法。 (2 )创建被代理的类BusinessClassService 以及接口BusinessClassServicelmpl 。 (3 )调用Proxy 的静态方法newProxyInstance ,创建一个代理类。 ( 4 )通过代理类调用方法。

spring aop实现日志框架

使用Spring AOP 的注解方式实现日志框架是非常简单的。首先,在配置文件 spring-mvc且nl 中添加配置, 具体代码如下:

 <aop:aspectj-autoproxy proxy-target-class="true">
  • </aop:aspectj-autoproxy>: 声明自动为Spring容器中那些配置@aspectJ切面的bean创建 代理,织入切面。<aop : aspectj -autoproxy />有一个proxy-target-class属性,默认为fal se, 表示使用JDK动态代理织入增强,当配置poxy-target-class 为true 时,表示使用CGLib动 态代理技术织入增强。不过即使设置proxy-target-class 为fa lse ,如果目标类没有声明接 口,则Spring将自动使用CGLib动态代理。

配置添加完成之后,要定义一个切面Loglnterceptor ,具体代码如下:

• @Aspect : 标识Loglntercepto r类为一个切面,供容器读取. • @Before : 在所拦截方法执行之前执行before 方法。 • @After:在所拦截方法执行之后执行after方法。 • @Around :可以同时在所拦截方法的前后执行一段逻辑。 • execution 切入点指示符: 表示在controller 包中定义的任意方法 的执行。execution 切入点指示符执行表达式的格式如下:

翻译为:

其中黑色字体部分不能省略,各部分都支持通配符“*”来匹配全部。比较特殊的为形参 表部分,其支持以下两种通配符:

例如:

下面举一些execution 的使用实例,具体内容见表3 -3 。

切面类Loglnterceptor 开发完成之后, 重新启动springmvc-mybatis-book 项目,项目成功启 动后,在浏览器输入网址: http: //localbost: 8080/user/findAll , 便可以在lntellij IDEA 开发工具的 控制台看到如下的打印信息:

最新文章

  1. Java虚拟机及运行时数据区
  2. JS 继承总结
  3. Entity Framework Code First (四)Fluent API - 配置属性/类型
  4. POJ 1312 Numerically Speaking
  5. python 三分钟入门
  6. 【USACO 1.5.2】回文质数
  7. zoj 3647 Gao the Grid
  8. CRM后期修改实体,新增货币类型字段 需要注意的问题
  9. ThinkPhp学习05
  10. 重启库,提示找不到mysqld
  11. hello2 源码分析
  12. 程序性能调优工具之gprob
  13. tensorflow在windows下的安装
  14. 2D空间中求线段与圆的交点
  15. PLSQL 问题小记
  16. openstack网络DVR
  17. grunt项目构建工具
  18. vscodes使用(一): 常用插件,在线与离线安装
  19. JavaScript正则式入门
  20. C++ STL 常用遍历算法

热门文章

  1. Codeforces 659D Bicycle Race【计算几何】
  2. HDU3430 (置换群循环节+中国剩余定理)
  3. CodeForces 596B Wilbur and Array
  4. IP聚合 ---百度之星(与运算)
  5. Openwrt挂载NTFS硬盘提示“只读”错误的解决方法!
  6. ZOJ 3316 Game 一般图最大匹配带花树
  7. 【spring+websocket的使用】
  8. [LeetCode]Two Sum 【Vector全局指针的使用】
  9. 分页语句-取出sql表中第31到40的记录(以自动增长ID为主键)
  10. 初识JVM虚拟机