`

温习温习 aop的原理

阅读更多
在我工作这几年里,spring aop 用得最多的有两点

1  事务通过aop来配置
2  判断service 或者dao 层 运行时间

那么原理是怎么样的呢? 我也没有想去细致的理解

首先 我们想实现一个功能
请看如下的类:


packagecom.aop;
 
/**
 * Created with IntelliJ IDEA.
 * User: zhangyong
 * Date: 13-2-11
 * Time: 下午10:23
 * To change this template use File | Settings | File Templates.
 */
publicinterfaceIHello {
 
    publicvoidsayHello();
 
}
1111
实现类如下:

packagecom.aop.impl;
 
importcom.aop.IHello;
 
importjava.lang.reflect.Proxy;
 
/**
 * Created with IntelliJ IDEA.
 * User: zhangyong
 * Date: 13-2-11
 * Time: 下午10:24
 * To change this template use File | Settings | File Templates.
 */
publicclassIHelloImplimplementsIHello {
 
    @Override
    publicvoidsayHello() {
        System.out.println("Hello come on");
    }
 
 
 
}


2  添加代理类来绑定接口

   代理类首先 需要实现 InvocationHandler

   所以 定义个代理类


  

packagecom.aop;
 
importorg.apache.log4j.Logger;
 
importjava.lang.reflect.InvocationHandler;
importjava.lang.reflect.Method;
importjava.lang.reflect.Proxy;
importjava.sql.Connection;
 
/**
 * hello的代理类
 * User: zhangyong
 * Date: 13-2-11
 * Time: 下午10:26
 * To change this template use File | Settings | File Templates.
 */
publicclassHelloProxyimplementsInvocationHandler {
 
    privatestaticLogger logger = Logger.getLogger(HelloProxy.class);
 
    privateIHello hello;
 
    publicHelloProxy(IHello hello) {
        this.hello = hello;
    }
 
    publicstaticIHello newInstance(IHello hello) {
        InvocationHandler handler =newHelloProxy(hello);
        ClassLoader classLoader = IHello.class.getClassLoader();
 
        return(IHello) Proxy.newProxyInstance(classLoader,newClass[]{IHello.class}, handler);
    }
 
    @Override
    publicObject invoke(Object proxy, Method method, Object[] args)throwsThrowable {
        logger.info("I am invoking starting");
        Object returnObj = method.invoke(hello, args);
        logger.info("I am invoking ending");
        returnreturnObj;
    }
 
 
}


ok ! 代理类写好了 我们需要写意个测试类 :


packagecom.aop;
 
importcom.aop.impl.IHelloImpl;
importorg.apache.commons.logging.Log;
importorg.apache.commons.logging.LogFactory;
 
importjava.sql.Connection;
 
/**
 * 测试aop
 * User: zhangyong
 * Date: 13-2-11
 * Time: 下午10:25
 * To change this template use File | Settings | File Templates.
 */
publicclassTestAop {
 
    privatestaticfinalLog log = LogFactory.getLog(Connection.class);
 
    publicstaticvoidmain(String[] args) {
        IHello hello = HelloProxy.newInstance(newIHelloImpl());
        hello.sayHello();
    }
 
}



运行结果如下:

2013-02-15 17:26:18,844  INFO main com.aop.HelloProxy:invoke(36) - I am invoking starting
Hello come on
2013-02-15 17:26:18,847  INFO main com.aop.HelloProxy:invoke(38) - I am invoking ending


另外在mybatis 里 当我们在log4j里配置好 输出的时候 比如:

log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG


就会打印响应的sql ,在mybatis里 涉及到的类是: ConnectionLogger



package org.apache.ibatis.logging.jdbc;

import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.reflection.ExceptionUtil;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;

/**
 * Connection proxy to add logging 添加日志的代理(好方法)
 */
public class ConnectionLogger extends BaseJdbcLogger implements InvocationHandler {

  private static final Log log = LogFactory.getLog(Connection.class);

  private Connection connection;

  private ConnectionLogger(Connection conn) {
    super();
    this.connection = conn;
    if (log.isDebugEnabled()) {//在log4j中配置
      log.debug("ooo Connection Opened");
    }
  }

  public Object invoke(Object proxy, Method method, Object[] params)
      throws Throwable {
    try {
      if ("prepareStatement".equals(method.getName())) {
        PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
        stmt = PreparedStatementLogger.newInstance(stmt, (String) params[0]);
        return stmt;
      } else if ("prepareCall".equals(method.getName())) {
        PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
        stmt = PreparedStatementLogger.newInstance(stmt, (String) params[0]);
        return stmt;
      } else if ("createStatement".equals(method.getName())) {
        Statement stmt = (Statement) method.invoke(connection, params);
        stmt = StatementLogger.newInstance(stmt);
        return stmt;
      } else if ("close".equals(method.getName())) {
        if (log.isDebugEnabled()) {
          log.debug("xxx Connection Closed");
        }
        return method.invoke(connection, params);
      } else {
        return method.invoke(connection, params);
      }
    } catch (Throwable t) {
      Throwable t1 = ExceptionUtil.unwrapThrowable(t);
      log.error("Error calling Connection." + method.getName() + ':', t1);
      throw t1;
    }

  }

  /**
   * Creates a logging version of a connection
   *
   * @param conn - the original connection
   * @return - the connection with logging
   */
  public static Connection newInstance(Connection conn) {
    InvocationHandler handler = new ConnectionLogger(conn); 
    ClassLoader cl = Connection.class.getClassLoader();
    return (Connection) Proxy.newProxyInstance(cl, new Class[]{Connection.class}, handler);
  }

  /**
   * return the wrapped connection
   *
   * @return the connection
   */
  public Connection getConnection() {
    return connection;
  }

}


它的调用方式是:

/** 根据日志级别 封装connection 若是DEBUG级别 则封装log **/
private Connection wrapConnection(Connection connection) {
  if (log.isDebugEnabled()) {
    return ConnectionLogger.newInstance(connection);
  } else {
    return connection;
  }
}
分享到:
评论
1 楼 pp_wen 2013-05-17  
求楼主头像原图 372791833@qq.com

相关推荐

    J2EE学习以及Linux组件学习的日常总结,适合想了解和温习基础知识的童鞋。目前计划包含的内容有设计模式、Spring.zip

    以及基于依赖注入(DI)和面向切面编程(AOP)的编程模型。Spring的核心特性之一就是控制反转(Inversion of Control,IoC),它将组件的创建和依赖关系的维护交由外部容器管理。 weathertop-master很可能是开源...

    Could not find agent

    Java代理是一种允许开发者在JVM上进行增强或拦截行为的技术,例如通过ASM、ByteBuddy等库来实现AOP(面向切面编程)。 在描述中,虽然内容为空,但我们可以推测博主可能在尝试运行一个包含Java代理的程序时遇到了...

    struts2.1.6+spring2.0+hibernate3.2常用配置包

    最近温习ssh2整合编程,顺便浏览下struts2有什么更新的消息,下载了新版本的struts2的2.1.8.1版,使用的是MyEclipse8.0开发,但是问题就随之而来了。MyEclipse8.0中自带的struts2版本是2.1.6,spring版本有2.0,2.5...

    springmybatis

    所以在此重新温习了一下 mybatis, 因此就有了这个系列的 mybatis 教程. 什么是mybatis MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果...

    计算机硬件控制_驱动级键盘鼠标同步_PS2接口UDP协议多机协同_基于rabirdwinio和pynput的跨设备输入共享系统_实现多台Windows电脑的键盘鼠标同步操作_支持.zip

    计算机硬件控制_驱动级键盘鼠标同步_PS2接口UDP协议多机协同_基于rabirdwinio和pynput的跨设备输入共享系统_实现多台Windows电脑的键盘鼠标同步操作_支持

    嵌入式八股文面试题库资料知识宝典-TCPIP协议栈.zip

    嵌入式八股文面试题库资料知识宝典-TCPIP协议栈.zip

    少儿编程scratch项目源代码文件案例素材-开膛手杰克.zip

    少儿编程scratch项目源代码文件案例素材-开膛手杰克.zip

    基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型

    基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型,个人经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做大作业的学生和需要项目实战练习的学习者,可作为毕业设计、课程设计、期末大作业,代码资料完整,下载可用。 基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型基于深度学习CNN网络+pytorch框架实现

    电力弹簧技术在主动配电网规划与运行优化调度中的应用研究

    内容概要:本文详细探讨了电力弹簧技术在主动配电网规划及运行优化调度中的应用。首先介绍了电力弹簧技术作为智能电网调控手段的优势,如自适应性强、响应速度快、节能环保等。接着阐述了主动配电网规划的目标和策略,包括优化电网结构、提高能源利用效率和降低故障风险。随后讨论了运行优化调度的原则和方法,强调了实时监测、智能调度策略以及优化调度模型的重要性。最后通过实际案例分析展示了电力弹簧技术在提升电网稳定性、可靠性和能效方面的显著效果,展望了其广阔的应用前景。 适合人群:从事电力系统规划、运行管理的研究人员和技术人员,以及对智能电网感兴趣的学者和学生。 使用场景及目标:适用于希望深入了解电力弹簧技术及其在主动配电网规划和运行优化调度中具体应用的专业人士。目标是掌握电力弹簧技术的工作原理、优势及其在实际项目中的实施方法。 其他说明:本文不仅提供了理论分析,还有具体的案例支持,有助于读者全面理解电力弹簧技术的实际应用价值。

    嵌入式八股文面试题库资料知识宝典-C语言思维导图.zip

    嵌入式八股文面试题库资料知识宝典-C语言思维导图.zip

    电路教学与科研案例的结合—以最大功率传输定理为例.pdf

    电路教学与科研案例的结合—以最大功率传输定理为例.pdf

    【HarmonyOS文件系统】分布式架构下的多设备协同与文件管理:构建万物互联新生态

    内容概要:本文深入介绍了HarmonyOS文件系统及其在万物互联时代的重要性。HarmonyOS自2019年发布以来,逐步覆盖多种智能设备,构建了庞大的鸿蒙生态。文件系统作为其中的“数字管家”,不仅管理存储资源,还实现多设备间的数据协同。文章详细介绍了常见的文件系统类型,如FAT、NTFS、UFS、EXT3和ReiserFS,各自特点和适用场景。特别强调了HarmonyOS的分布式文件系统(hmdfs),它通过分布式软总线技术,打破了设备界限,实现了跨设备文件的无缝访问。此外,文章对比了HarmonyOS与Android、iOS文件系统的差异,突出了其在架构、跨设备能力和安全性方面的优势。最后,从开发者视角讲解了开发工具、关键API及注意事项,并展望了未来的技术发展趋势和对鸿蒙生态的影响。 适合人群:对操作系统底层技术感兴趣的开发者和技术爱好者,尤其是关注物联网和多设备协同的用户。 使用场景及目标:①理解HarmonyOS文件系统的工作原理及其在多设备协同中的作用;②掌握不同文件系统的特性和应用场景;③学习如何利用HarmonyOS文件系统进行应用开发,提升跨设备协同和数据安全。 阅读建议:本文内容详实,涵盖了从基础概念到高级开发技巧的多个层次,建议读者结合自身需求,重点关注感兴趣的部分,并通过实践加深理解。特别是开发者可参考提供的API示例和开发技巧,尝试构建基于HarmonyOS的应用。

    嵌入式八股文面试题库资料知识宝典-海康嵌入式笔试题.zip

    嵌入式八股文面试题库资料知识宝典-海康嵌入式笔试题.zip

    三电平有源电力滤波器仿真:基于瞬时无功功率理论的双闭环控制与SVPWM调制技术

    内容概要:本文详细介绍了基于瞬时无功功率理论的三电平有源电力滤波器(APF)仿真研究。主要内容涵盖并联型APF的工作原理、三相三电平NPC结构、谐波检测方法(ipiq)、双闭环控制策略(电压外环+电流内环PI控制)以及SVPWM矢量调制技术。仿真结果显示,在APF投入前后,电网电流THD从21.9%降至3.77%,显著提高了电能质量。 适用人群:从事电力系统研究、电力电子技术开发的专业人士,尤其是对有源电力滤波器及其仿真感兴趣的工程师和技术人员。 使用场景及目标:适用于需要解决电力系统中谐波污染和无功补偿问题的研究项目。目标是通过仿真验证APF的有效性和可行性,优化电力系统的电能质量。 其他说明:文中提到的仿真模型涉及多个关键模块,如三相交流电压模块、非线性负载、信号采集模块、LC滤波器模块等,这些模块的设计和协同工作对于实现良好的谐波抑制和无功补偿至关重要。

    基于环比增长的销售统计分析——2019年中青杯全国数学建模竞赛C题.pdf

    基于环比增长的销售统计分析——2019年中青杯全国数学建模竞赛C题.pdf

    嵌入式八股文面试题库资料知识宝典-linux面试题.zip

    嵌入式八股文面试题库资料知识宝典-linux面试题.zip

    嵌入式八股文面试题库资料知识宝典-linux常见面试题.zip

    嵌入式八股文面试题库资料知识宝典-linux常见面试题.zip

    基于Matlab的小电流接地系统单相故障仿真分析及其应对策略研究

    内容概要:本文探讨了小电流接地系统在配电网络中的应用,特别是在单相故障情况下的仿真分析。文中介绍了小电流接地系统的背景和发展现状,重点讨论了两种常见的接地方式——中性点不接地和中性点经消弧线圈接地。利用Matlab作为仿真工具,作者构建了详细的电路模型,模拟了单相故障的发生过程,并通过多个结果图表展示了故障电流、电压波形及系统运行状态。此外,文章还包括了详细的设计说明书和PPT介绍,帮助读者全面理解仿真过程和技术细节。 适合人群:从事电力系统研究、维护的技术人员,尤其是关注配电网络安全和稳定的工程师。 使用场景及目标:适用于希望深入了解小电流接地系统的工作原理和故障处理机制的专业人士。通过本研究,读者可以掌握如何使用Matlab进行电力系统仿真,评估不同接地方式的效果,优化配电网络的安全性能。 其他说明:随文附带完整的仿真工程文件、结果图、设计说明书及PPT介绍,便于读者进一步探索和实践。

    少儿编程scratch项目源代码文件案例素材-激烈的殴斗.zip

    少儿编程scratch项目源代码文件案例素材-激烈的殴斗.zip

    嵌入式八股文面试题库资料知识宝典-小米嵌入式软件工程师笔试题目解析.zip

    嵌入式八股文面试题库资料知识宝典-小米嵌入式软件工程师笔试题目解析.zip

Global site tag (gtag.js) - Google Analytics