【转】通过BeanNameAutoProxyCreator改变臃肿代码
https://www.cnblogs.com/zdd-java/p/7861824.html
前言:
最近接手了一个项目,大概过了下需求,然后打开项目准备开搞的时候发现一个问题,这个项目是提供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改变臃肿代码
前言: 最近接手了一个项目,大概过了下需求,然后打开项目准备开搞的时候发现一个问题,这个项目是提供rest服务的一个web项目,其中很多旧系统由于还没改成微服务,所以只能通过HttpClient发起调 ...
- 改变你代码习惯的ES6
最近读阮一峰老师的ES6标准入门,让我感觉到了ES6的强大之处,读书之余整理了一些笔记,因为边读边记录的,所以可能会比较杂乱. ECMAScript和Javascript的关系 1996年11月,Ja ...
- Eclipse改变相同代码高亮颜色
一.点击某一代码时,让相同代码高亮显示(Eclipse默认是这样的) Window ->preferences ->Java ->Editor ->Mark Occurrenc ...
- Web前端开发最佳实践(10):JavaScript代码不好读,不好维护?你需要改变写代码的习惯
前言 这篇文章本应该在上一篇文章:使用更严格的JavaScript编码方式,提高代码质量之前发布,但当时觉得这篇文章太过基础,也就作罢.后来咨询了一些初级的开发者,他们觉得有必要把这篇文章也放上来.尽 ...
- CMFCPropertyGridCtrl的属性改变事件代码
//用于区分Prop, 使用SetData, GetData方法 CMFCPropertyGridProperty* pProp1 = new CMFCPropertyGridProperty(str ...
- cesium 检测视图改变的代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- iOS开发系列--Objective-C之协议、代码块、分类
概述 ObjC的语法主要基于smalltalk进行设计的,除了提供常规的面向对象特性外,还增加了很多其他特性,这一节将重点介绍ObjC中一些常用的语法特性.当然这些内容虽然和其他高级语言命名不一样,但 ...
- 建模分析之机器学习算法(附python&R代码)
0序 随着移动互联和大数据的拓展越发觉得算法以及模型在设计和开发中的重要性.不管是现在接触比较多的安全产品还是大互联网公司经常提到的人工智能产品(甚至人类2045的的智能拐点时代).都基于算法及建模来 ...
- iOS学习之代码块(Block)
代码块(Block) (1)主要作用:将一段代码保存起来,在需要的地方调用即可. (2)全局变量在代码块中的使用: 全局变量可以在代码块中使用,同时也可以被改变,代码片段如下: ;//注意:全局变量 ...
随机推荐
- Django:ORM中ForeignKey外键关系分析
假设有两张表,Role和User,因为多个用户会对应一个角色,属于多对一关系,所以User中的rolename字段使用ForeignKey,第一个参数为要关联的表Role,第二个参数related_n ...
- Freemarker讲解
FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP.它不仅可以用作表现层的实现 ...
- 最新 医渡云java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.医渡云等10家互联网公司的校招Offer,因为某些自身原因最终选择了医渡云.6.7月主要是做系统复习.项目复盘.LeetCo ...
- flask 密钥问题
RuntimeError RuntimeError: The session is unavailable because no secret key was set. Set the secret_ ...
- 035 Android 广播(BroadCastReceiver)
1.介绍 2.实现方法 3.注册广播 (1)静态广播 在AndroidManifest.xml文件中注册广播 <intent-filter>为过滤器 <receiver androi ...
- 1.IO的演进
1.Java IO 演进之路 本文围绕着一下几个问题 1.Java 中 BIO.NIO.AIO 之间的区别及应用场景. 2.阻塞(Block)与非阻塞(Non-Block)区别. 3.同步(Syn ...
- 【MIT 6.824 】分布式系统 课程笔记(二)Lecture 03 : GFS
Lecture 03 : GFS 一.一致性 1, 弱一致性 可能会读到旧数据 2, 强一致性 读到的数据都是最新的 3, 一致性比较 强一致性对于app的写方便, 但是性能差 弱一致性有良好的性能, ...
- 以php中的比较运算符操作整型,浮点型,字符串型,布尔型和空类型
字符,数字,特殊符号的比较依赖ASC II表,本表原先有127个,后来又扩充了一些,里面包含了奇奇奇怪的符号. ASC II表 https://baike.baidu.com/item/ASCII/3 ...
- Volatile的应用场景
1.当一个变量可能会被意想不到的更新时,要使用volatile来声明该变量,告诉编译器它所修饰的变量的值可能会在任何时刻被意外的更新. 2.语法 volatile int foo; int volat ...
- 【HC89S003F4开发板】 2调度器
HC89S003F4开发板调度器调试 一.前言 逛论坛看到有人给HC89做了调度器,调度部分直接操作堆栈的. 下载链接 下载下来调试看看. 二.用户代码 @实现效果 编译后led灯闪烁 #includ ...