博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring AOP 本质(4)
阅读量:7105 次
发布时间:2019-06-28

本文共 2571 字,大约阅读时间需要 8 分钟。

这一主要看看Spring AOP是如何实现通知包围的。
 
Spring AOP包围通知在功能上和前置通知加后置通知类似,但还是有区别的:包围通知可以修改返回值,还可以阻止、替换目标方法的执行。
 
Spring里的包围通知是实现MethodInterceptor接口的拦截器。
 
Spring包围通知有着很广泛的应用,比如远程代理和事务管理,都是由拦截器完成。另外,拦截器也是剖析程序运行的好方法。
 
下面利用Spring AOP包围通知实现监控业务方法的执行运行过程耗时情况。
 
/** 
* 业务组件 
*/
 
public 
class WorkerBean { 
    
public 
void doSomeWork(
int noOfTimes) { 
        
for(
int x = 0; x < noOfTimes; x++) { 
            work(); 
        } 
    } 
     
    
private 
void work() { 
        System.out.print(""); 
    } 
}
 
import java.lang.reflect.Method; 
import org.aopalliance.intercept.MethodInterceptor; 
import org.aopalliance.intercept.MethodInvocation; 
import org.springframework.util.StopWatch; 
/** 
* 拦截器,实现方法包围通知 
*/
 
public 
class ProfilingInterceptor 
implements MethodInterceptor { 
    
public Object invoke(MethodInvocation invocation) 
throws Throwable { 
        
//启动一个 stop watch 
        StopWatch sw = 
new StopWatch(); 
        
//运行计时器 
        sw.start(invocation.getMethod().getName()); 
        
//执行业务方法 
        Object returnValue = invocation.proceed(); 
        
//停止计时器 
        sw.stop(); 
        
//垃圾信息输出 
        dumpInfo(invocation, sw.getTotalTimeMillis()); 
        
//返回业务方法返回值 
        
return returnValue; 
    } 
    
/** 
     * 垃圾信息输入方法,实际上输出的是方法运行的计时信息 
     */
 
    
private 
void dumpInfo(MethodInvocation invocation, 
long ms) { 
        
//获取被调用方法 
        Method m = invocation.getMethod(); 
        
//获取被调用方法所属的对象 
        Object target = invocation.getThis(); 
        
//获取被调用方法的参数 
        Object[] args = invocation.getArguments(); 
        System.out.println(
"所执行的方法: " + m.getName()); 
        System.out.println(
"对象的类型: " + target.getClass().getName()); 
        System.out.println(
"方法的参数:"); 
        
for (
int x = 0; x < args.length; x++) { 
            System.out.print(
"    > " + args[x]); 
        } 
        System.out.print(
"\n"); 
        System.out.println(
"抓取方法运行的时间: " + ms + 
" ms"); 
    } 
}
 
import org.springframework.aop.framework.ProxyFactory; 
/** 
* 客户端测试方法 
*/
 
public 
class ProfilingExample { 
    
public 
static 
void main(String[] args) { 
        
//创建代理对象 
        WorkerBean bean = getWorkerBean(); 
        
//在代理对象上调用业务方法 
        bean.doSomeWork(10000000); 
    } 
    
/** 
     * 代理对象工厂 
     */
 
    
private 
static WorkerBean getWorkerBean() { 
        
//创建目标对象 
        WorkerBean target = 
new WorkerBean(); 
        
//构建代理对象工厂 
        ProxyFactory factory = 
new ProxyFactory(); 
        factory.setTarget(target); 
        factory.addAdvice(
new ProfilingInterceptor()); 
        
//生产一个代理对象 
        
return (WorkerBean)factory.getProxy(); 
    } 
}
 
运行结果:
- Using JDK 1.4 collections 
所执行的方法: doSomeWork 
对象的类型: com.apress.prospring.ch6.profiling.WorkerBean 
方法的参数: 
    > 10000000 
抓取方法运行的时间: 3453 ms 
Process finished with exit code 0
 
从输出的结果中,可以看到程序方法调用的方法名、参数、所属类,以及执行方法所耗费的时间。
 
另外说一下org.springframework.util.StopWatch类,这是个计时器类,此工具类主要可以获取计时器类start()和stop()两次方法调用间的时间。具体可以查看Spring的API文档。另外,我也在apache commons 包里面也有org.apache.common.lang.time.StopWatch。

http://lavasoft.blog.51cto.com/62575/75342/

 

转载于:https://www.cnblogs.com/softidea/p/5789790.html

你可能感兴趣的文章
html查看器android
查看>>
从零打造B/S 自动化运维平台 (一、自动化运维平台的应用及业务流程)
查看>>
shell中使用FTP
查看>>
linux运维实用的42个常用命令总结
查看>>
MySQL分库分表python实现分库(7th)
查看>>
OSPF虚链路virtual-link
查看>>
使用WM_QUIT终止线程
查看>>
String字符串的常用方法
查看>>
文件和目录权限chmod、更改所有者和所属组chown、umask、隐藏权限lsattr/chattr
查看>>
开启华为交换机路由器ssh访问
查看>>
linux 中的sar命令 与gnuplot绘图
查看>>
解决网站遭CC攻击(转载)
查看>>
Spring 项目全介绍
查看>>
Android应用程序组件Content Provider的启动过程源代码分析(3)
查看>>
部署及配置ISCSI Target,Livemigration系列之三
查看>>
rundeck Web页面配置node节点
查看>>
Java程序员,笔试必读
查看>>
linux 下 eclipse 开发环境的搭建
查看>>
android中DatePicker&TimePicker的应用
查看>>
JavaScript和C#通用gb2312和utf8编码解码函数简单实现
查看>>