【原】通过BeanNameAutoProxyCreator改变臃肿代码
前言:
最近接手了一个项目,大概过了下需求,然后打开项目准备开搞的时候发现一个问题,这个项目是提供rest服务的一个web项目,其中很多旧系统由于还没改成微服务,所以只能通过HttpClient发起调用。之前的开发人员为了监控每个方法的执行时间,在方法开始和结束写了很多logger.info("耗时:"+time)这种代码。很显然这是不规范的,当项目里到处有这样的代码存在降低了代码的可读性,于是改造后如下:
#创建一个方法拦截器:
/**
* 用来监控方法的执行时间-- 对应配置文件是spring-servlet.xml
* PS:必须放到springmvc的配置文件里,放在spring父容器里面由于先初始化的是spring父容器上下文,先实例化的是除@Controller外的bean,所以无法生成代理。
*
* @author dada
* @version $Id: MethodTimeAdvice.java, v 0.1
* @date 2017年11月15日 09:47:23
*/
public class MethodTimeAdvice implements MethodInterceptor { private final static Logger logger = Logger.getLogger("DAL-MONITOR"); /**
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
*/
public Object invoke(MethodInvocation invocation) throws Throwable {
//用 commons-lang 提供的 StopWatch 计时,Spring 也提供了一个 StopWatch
StopWatch clock = new StopWatch();
clock.start(); //计时开始
Object result = null;
//监控的方法名
String methodName = getRequestMappingName(invocation);
if(null == methodName){
methodName = invocation.getMethod().getDeclaringClass().getSimpleName();
}
try {
//这个是我们监控的bean的执行并返回结果
result = invocation.proceed();
} catch (Throwable e) {
//监控的类名
String className = invocation.getMethod().getDeclaringClass().getSimpleName();
//监控的参数
Object[] objs = invocation.getArguments();
logger.error("控制层执行异常,方法名:" + className + "参数: " + getString(objs), e);
throw e;
}
clock.stop(); //计时结束
if (logger.isInfoEnabled()) {
logger.info("[ " + methodName + " ] 执行时间:" + clock.getTime() + " ms ");
}
return result;
} /**
* 这个类主要是用于输出方法的参数
*
* @param objs
* @return
*/
@SuppressWarnings("unchecked")
public String getString(Object[] objs) {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0, len = objs.length; i < len; i++) {
if (objs[i] instanceof String) {
stringBuffer.append("String类型:" + objs[i].toString());
} else if (objs[i] instanceof Map) {
HashMap<String, Object> hashMap = (HashMap<String, Object>) objs[i];
HashMap<String, Object> map = hashMap;
HashSet<String> set = (HashSet<String>) map.keySet();
stringBuffer.append("Map类型");
for (String str : set) {
stringBuffer.append(str + "=" + map.get(str));
}
} else if (objs[i] instanceof Integer) {
stringBuffer.append("整数类型:");
stringBuffer.append(objs[i].toString());
} else {
stringBuffer.append(objs[i].toString());
}
}
return stringBuffer.toString();
} public String getRequestMappingName(MethodInvocation invocation){
Method method = invocation.getMethod();
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
if(requestMapping!=null){
return requestMapping.name();
}
return null;
}
}
#配置 Spring BeanNameAutoProxyCreator, 用来拦截上面的 MethodTimeAdvice,切记必须放到spring-mvc.xml配置里,因为已经测试过如果放到spring的xml里面会导致扫描不到从而无法切面。
<bean id="methodTimeAdvice" class="com.i2p.admin.interceptor.MethodTimeAdvice" />
<!-- 根据 Bean 的名字自动实现代理拦截 -->
<bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>methodTimeAdvice</value>
</list>
</property>
<property name="beanNames">
<list>
<!-- 添加到其中的 Bean 自动就被代理拦截了(下面的是对应的bean的名称,那么当请求InnovatePartBorrowController任何一个方法都会执行MethodTimeAdvice里面的Invoke方法) -->
<value>innovatePartBorrowController</value>
</list>
</property>
</bean>
#其中上面的配置里innovatePartBorrowController就是需要被打印的类。
总结:
通过spring 代理,不仅减少了代码的copy工作,同时又方便管理;至于后续如果有新的类需要实现打印功能,我们只需要在spring-mvc.xml里配置好对应的bean就能实现日志的打印。
【原】通过BeanNameAutoProxyCreator改变臃肿代码的更多相关文章
- 【转】通过BeanNameAutoProxyCreator改变臃肿代码
https://www.cnblogs.com/zdd-java/p/7861824.html 前言: 最近接手了一个项目,大概过了下需求,然后打开项目准备开搞的时候发现一个问题,这个项目是提供res ...
- 改变你代码习惯的ES6
最近读阮一峰老师的ES6标准入门,让我感觉到了ES6的强大之处,读书之余整理了一些笔记,因为边读边记录的,所以可能会比较杂乱. ECMAScript和Javascript的关系 1996年11月,Ja ...
- 【原】如何改变表单元素的外观(for Webkit and IE10)
表单元素在网页设计中使用的非常频繁,如文本输入框.单选框.复选框.选择列表.上传文件,它们在浏览器中的展现有自带的外观,为了在视觉上取得更好的产品体验,保持客户端的统一,通常产品经理会提出需要改变它的 ...
- [原][osgearth]OE地形平整代码解读
在FlatteningLayer文件的createHeightField函数中:使用的github在2017年1月份的代码 if (!geoms.getComponents().empty()) { ...
- Eclipse改变相同代码高亮颜色
一.点击某一代码时,让相同代码高亮显示(Eclipse默认是这样的) Window ->preferences ->Java ->Editor ->Mark Occurrenc ...
- Web前端开发最佳实践(10):JavaScript代码不好读,不好维护?你需要改变写代码的习惯
前言 这篇文章本应该在上一篇文章:使用更严格的JavaScript编码方式,提高代码质量之前发布,但当时觉得这篇文章太过基础,也就作罢.后来咨询了一些初级的开发者,他们觉得有必要把这篇文章也放上来.尽 ...
- (原)C++中测试代码执行时间
转载请注明出处(不过这个用法网上到处都是): http://www.cnblogs.com/darkknightzh/p/4987738.html LARGE_INTEGER nFreq, nBegi ...
- HTML之打开/另存为/打印/刷新/查看原文件等按钮的代码
■打开■ <input name=Button onClick=document.all.WebBrowser.ExecWB(1,1) type=button value=打开> < ...
- 【原】wow64 x86/x64 代码切换过程分析
下面以ntdll32!ZwQueryInformationProcess API为例分析 x86代码与x64代码之间的切换过程, 32bit的test程序: step1: ntdll32!ZwQuer ...
随机推荐
- [solution] JZOJ-5781 秘密通道
JZOJ-5781[秘密通道 ]solution 题面 Description 有一副$nm$的地图,有$nm$块地,每块是下列四种中的一种: 墙:用#表示,墙有4个面,分别是前面,后面,左面,右面. ...
- Qt中的CSS配置(QDarkStyleSheet)
QDarkStylesheet gihub地址 https://github.com/ColinDuquesnoy/QDarkStyleSheet
- 关不掉的小姐姐程序python tkinter实现 学习---打包教程
首先,我们先准备两个.py文件,还要图片文件 代码//是我自己手写的,copy时记得删掉,不然有可能错误,比如中英文啥的 当然 一些语法的无问题就百度,都能给你答案 第一个.py ...
- WITH RECOMPILE 和 OPTION(RECOMPILE) 使用上的区别
在考虑重编译T-SQL(或者存储过程)的时候,有两种方式可以实现强制重编译(前提是忽略导致重编译的其他因素的情况下,比如重建索引,更新统计信息等等), 一是基于WITH RECOMPILE的存储过程级 ...
- FFmpeg原始帧处理-滤镜API用法详解
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10429145.html 在FFmpeg中,滤镜(filter)处理的是未压缩的原始音视频 ...
- Android 经验之文件下载
在Android 开发中,我们肯定会接触到下载需求,那么如何通过技术实现呢? 一.简单实现: 通过了解HTTP原理,我们应该可以知道,HTTP学习的时候,可以通过HTTPGET方式来进行文件下载: n ...
- 腾讯Alloy团队代码规范
概述 我个人很看重代码规范,因为代码是写给别人看的,按规范写别人才更容易理解.之前苦于没有代码规范的资料,现在在github上面看到了腾讯Alloy团队的代码规范,于是学习了一下,并记录下我自己还没怎 ...
- 处理返回键劫持(结合vue)
在这里记录一下近期解决的一个问题 需求,在某个页面,浏览器返回按钮点击的时候,不能走浏览器的默认返回操作,而是要走自己的逻辑, 比如跳转页面等等. 那么问题来了,如何去不走默认返回呢.经过网上搜罗和同 ...
- struts2框架学习笔记5:OGNL表达式
OGNL取值范围分两部分,root.Context两部分 可以放置任何对象作为ROOT,CONTEXT中必须是Map键值对 示例: 准备工作: public void fun1() throws Ex ...
- Typescript 学习笔记一:介绍、安装、编译
前言 整理了一下 Typescript 的学习笔记,方便后期遗忘某个知识点的时候,快速回忆. 为了避免凌乱,用 gitbook 结合 marketdown 整理的. github地址是:ts-gitb ...