`
ginge
  • 浏览: 208618 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

打印出,入口参数和执行时间--AOP简单应用

阅读更多

项目进入ST的时候,为了定位问题处于哪个模块。需要明确知道出入中的参数的值以追寻问题的根源。这经常需要编写大量的打印语句。可能有些人会写这些东西,但是有些人却忘记写了。也有人通过完整的Unit Testing确信自己的代码没有问题。可是当问题出现时,事情不会这么容易解决。因为人家可能也做了测试,只不过漏了测试某些分支而导致问题发生了。这个时候就需要证据了。一种方法是把出入口参数的值一一打印出来。可是这些语句要是散落在各个类里就太丑陋了,维护起来也费劲。

 

利用AOP我们可以一下这方面的事情。以下的主要的代码片段:

public Object cut(ProceedingJoinPoint pjp)
			throws Throwable {
		
		
		String instanceMethod = 
			pjp.getTarget().getClass() + "@" + pjp.getTarget().hashCode() + "]"+"." + pjp.getSignature().getName();
		if(this.isPrintArguments())
		{
			this.printArguments(instanceMethod, pjp.getArgs());
		}
		
		
		Object rel = null;
		
		long start = System.nanoTime();
		
		try
		{
			rel = pjp.proceed();
		}catch(Exception e)
		{
			if(this.isCatchException())
			{
				if(log.isErrorEnabled())
				{
					log.error("Exception occure while executing.", e);
				}
			}
			
			throw e;
		}
		
		long end = System.nanoTime();
		
		if(this.isPrintInvocationTime())
		{
			if(log.isDebugEnabled())
			{
				log.debug("["+(end - start)+"] nanoseconds elapsed executing [" + instanceMethod );
			}
		}
		
		
		if(this.isPrintReturnValue())
		{
			printReturnVal(rel);
		}
		
		log.debug("");
		
		return rel;
	}

 

样本配置如下:

<aop:config>
		<aop:aspect id="com.bee.fw.core.methodInvocationAspect" ref="com.bee.fw.core.MethodInvocationDetailsInspector">
			<aop:pointcut id="com.bee.fw.core.cutExpresseion"
				expression="execution(* com.bee.fw.debug.Aspect.*(..))" />
			<aop:around pointcut-ref="com.bee.fw.core.cutExpresseion" method="cut" />
		</aop:aspect>
	</aop:config>
	
	<bean id="com.bee.fw.core.MethodInvocationDetailsInspector" class="com.bee.fw.debug.MethodInvocationDetailsInspector">
		<property name="printInvocationTime" value="true" />
		<property name="order" value="100" />
	</bean>
	
	<bean id="com.bee.fw.core.Aspect" class="com.bee.fw.debug.Aspect">
	</bean>

 

这个代码依赖的类库有:

Spring >= 2.0

Commons-io >= 1.3.1

Commons-logging >=1.1

Commons-beanUtils > 1.8.0

Log4j >= 1.2.13

 

有兴趣的可以查看附件的源码和程序执行的效果。

 

1
0
分享到:
评论
2 楼 ginge 2009-03-03  
2009-03-03 16:54:34 DEBUG (MethodInvocationDetailsInspector.java:92)     - Intercepting:class com.bee.fw.debug.Aspect@18481629].invoke2, Arguments:
2009-03-03 16:54:34 DEBUG (MethodInvocationDetailsInspector.java:98)     -   [0]:java.lang.String@18f7386[value={I,',m, },offset=0,count=4,hash=2215633]
2009-03-03 16:54:34 DEBUG (MethodInvocationDetailsInspector.java:98)     -   [1]:java.lang.String@182ef6b[value={ ,G,i,n,g,e,!},offset=0,count=7,hash=468365303]
2009-03-03 16:54:34 DEBUG (MethodInvocationDetailsInspector.java:104)     -
2009-03-03 16:54:34 DEBUG (MethodInvocationDetailsInspector.java:68)     - [63695] nanoseconds elapsed executing [class com.bee.fw.debug.Aspect@18481629].invoke2
2009-03-03 16:54:34 DEBUG (MethodInvocationDetailsInspector.java:77)     -   Returned Valued:
2009-03-03 16:54:34 DEBUG (MethodInvocationDetailsInspector.java:78)     -                   java.lang.String@1f02b85[value={I,',m, , ,G,i,n,g,e,!},offset=0,count=11,hash=-442842106]
1 楼 ginge 2009-03-03  
有兴趣的可以进一步查看附件中的FieldsReflectionToStringBuilder类。
当出入口参数是对象时,还可以通过在classpath中放置acceptedFieldClasses.cnf和excludededFieldClasses.cnf文件指定特定类型的字段才打印。

其中acceptedFieldClasses.cnf和excludededFieldClasses.cnf文件一行放置一个类。全路径和类名都需要指定。

其它的需求根据自己的需要实现。

相关推荐

Global site tag (gtag.js) - Google Analytics