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

SpringAOP应用-日志输出耗时统计

阅读更多

一、采用@AspectJ注解来实现

       1、在Spring配置文件中启用AspectJ<aop:aspectj-autoproxy />。同时需要在应用程序的classpath中引入两个AspectJ库:aspectjweaver.jar aspectjrt.jar

       2、定义用到的切面(@Aspect)类:包含切点(@Pointcut和通知。

       注:A可以单独定义切点,然后通过切点的引用来定义通知;也可以使用一个in-place 的切入点表达式直接定义通知。

       B通知的参数

       3、在Spring配置文件中,配置切面Bean。(切记在配置文件中配置Abject

示例:配置部分

	<aop:aspectj-autoproxy />
	<bean id="logAdviceAspect"
		class="com.aspects.LogAdviceAspect">
	</bean>

Bean部分示例:

@Aspect
public class LogAdviceAspect {
	private static Logger log = Logger.getLogger(LogAdviceAspect.class);
	
	@Around("execution(* test.TestStruts.*(..))")
	public Object doBasicProfilingTime(ProceedingJoinPoint pjp) throws Throwable {
		log.debug("Takes: start...........  ");
		//org.apache.commons.lang.time.StopWatch
		StopWatch clock = new StopWatch();
		clock.start(); // 计时开始
		Object retVal = pjp.proceed();
		clock.stop(); // 计时结束		
		log.debug("Takes:" + clock.getTime() + " ms  ");	
		return retVal;
	}
}

 

 

 

 

二、采用基于模式(schema-based)的方式来实现

       1、定义用到的日志或者时间计算类:主要包含相应通知对应的实现方法。

       2、在Spring配置文件中,配置步骤1中的Bean

       3、在Spring配置文件中,配置AOP信息。

示例:配置部分

	<aop:config>
		<aop:aspect id="test" ref="timeAdvice">
			<aop:pointcut id="idempotentOperation"
				expression="execution(* test.TestStruts.*(..))" />
			<aop:around pointcut-ref="idempotentOperation"
				method="doBasicProfilingTime" />
		</aop:aspect>
	</aop:config>
	<bean id="timeAdvice"
		class="com.aspects.TestAspect">
	</bean>

 

Bean部分示例:

public class TestAspect {
	protected final Log log = LogFactory.getLog(this.getClass());
	
	public Object doBasicProfilingTime(ProceedingJoinPoint pjp) throws Throwable {
		//org.apache.commons.lang.time.StopWatch
		StopWatch clock = new StopWatch();
		clock.start(); // 计时开始
		Object retVal = pjp.proceed();
		clock.stop(); // 计时结束		
		log.debug("Takes:" + clock.getTime() + " ms  ");		
		return retVal;
	}
}

 

 

三、采用基于模式(schema-based)和Interceptor的方式来实现

       1、定义用到的日志或者时间计算类:该类实现Interceptor接口。

       2、在Spring配置文件中,配置步骤1中的Bean

       3、在Spring配置文件中,配置AOP信息。

示例:配置部分

 

	<aop:config>
		<aop:advisor id="methodTimeLog" advice-ref="methodTimeAdvice"
			pointcut="execution(* *..service..*(..))" />
	</aop:config>
	<bean id="methodTimeAdvice" class="com.aspects.MethodTimeAdvice" />

  

Bean部分示例:

 

public class MethodTimeAdvice implements MethodInterceptor {
	protected final Log log = LogFactory.getLog(MethodTimeAdvice.class);

	public Object invoke(MethodInvocation invocation) throws Throwable {
		// 用 commons-lang 提供的 StopWatch 计时
		StopWatch clock = new StopWatch();
		clock.start(); // 计时开始
		Object result = invocation.proceed();
		clock.stop(); // 计时结束

		// 方法参数类型,转换成简单类型
		Class[] params = invocation.getMethod().getParameterTypes();
		String[] simpleParams = new String[params.length];
		for (int i = 0; i < params.length; i++) {
			simpleParams[i] = params[i].getSimpleName();
		}

		log.debug("Takes:" + clock.getTime() + " ms ["
				+ invocation.getThis().getClass().getName() + "."
				+ invocation.getMethod().getName() + "("
				+ StringUtils.join(simpleParams, ",") + ")] ");

		return result;
	}
}

 

 

注:几种通知需要实现的Interceptor接口分别为:

       1Around通知:org.aopalliance.intercept.MethodInterceptor

       2Before通知:org.springframework.aop.MethodBeforeAdvice

       3AfterReturning通知:org.springframework.aop.AfterReturningAdvice

       4AfterThrowing通知:org.springframework.aop.ThrowsAdvice

 

 

附录A:遇到异常

java.lang.NoClassDefFoundError:org/objectweb/asm/commons/EmptyVisitor

解决办法是:

1.去掉类路径上的关于Hibernate3lib

asm.jar

asm-attrs.jar

cglib-2.1.3.jar

2.加入Spring中的以下4lib

asm-2.2.2.jar

asm-commons-2.2.2.jar

asm-util-2.2.2.jar

cglib-nodep-2.1_3.jar

异常分析详见:http://royboy.iteye.com/blog/142449

 

附录B:常见的切入点(pointcut)定义(参阅:spring2.0-reference_final_zh_cn.chm

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SystemArchitecture {

  /**
   * A join point is in the web layer if the method is defined
   * in a type in the com.xyz.someapp.web package or any sub-package
   * under that.
   */
  @Pointcut("within(com.xyz.someapp.web..*)")
  public void inWebLayer() {}

  /**
   * A join point is in the service layer if the method is defined
   * in a type in the com.xyz.someapp.service package or any sub-package
   * under that.
   */
  @Pointcut("within(com.xyz.someapp.service..*)")
  public void inServiceLayer() {}

  /**
   * A join point is in the data access layer if the method is defined
   * in a type in the com.xyz.someapp.dao package or any sub-package
   * under that.
   */
  @Pointcut("within(com.xyz.someapp.dao..*)")
  public void inDataAccessLayer() {}

  /**
   * A business service is the execution of any method defined on a service
   * interface. This definition assumes that interfaces are placed in the
   * "service" package, and that implementation types are in sub-packages.
   * 
   * If you group service interfaces by functional area (for example, 
   * in packages com.xyz.someapp.abc.service and com.xyz.def.service) then
   * the pointcut expression "execution(* com.xyz.someapp..service.*.*(..))"
   * could be used instead.
   */
  @Pointcut("execution(* com.xyz.someapp.service.*.*(..))")
  public void businessService() {}
  
  /**
   * A data access operation is the execution of any method defined on a 
   * dao interface. This definition assumes that interfaces are placed in the
   * "dao" package, and that implementation types are in sub-packages.
   */
  @Pointcut("execution(* com.xyz.someapp.dao.*.*(..))")
  public void dataAccessOperation() {}

}

 

常见切入点表达式的例子:

1、任意公共方法的执行:execution(public * *(..))

2、任何一个以“set”开始的方法的执行:execution(* set*(..))

3AccountService 接口的任意方法的执行:

execution(* com.xyz.service.AccountService.*(..))

4、定义在service包里的任意方法的执行:execution(* com.xyz.service.*.*(..))

5、定义在service包或者子包里的任意方法的执行:

       execution(* com.xyz.service..*.*(..))

6、在service包里的任意连接点(在Spring AOP中只是方法执行):

       within(com.xyz.service.*)

7、在service包或者子包里的任意连接点(在Spring AOP中只是方法执行):

       within(com.xyz.service..*)

 

 

分享到:
评论
2 楼 40020072 2008-09-07  
不错 受教啦
1 楼 aumy2008 2008-08-08  
备注:
如果将AOP切点配置在Struts2的Action层,当访问action时,抛出类似java.lang.NoSuchMethodException: $Proxy52.showAppliers()
这样的异常,则可以使用<aop:aspectj-autoproxy proxy-target-class="true"/>或者<aop:config proxy-target-class="true">来强制使用cglib类代理来解决异常。

相关推荐

    开发工具 spring-aop-4.3.6.RELEASE

    开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE...

    spring-aop.jar各个版本

    spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...

    Spring AOP--日志管理

    Spring AOP--日志管理,注释齐全,欢迎大家共同交流。

    Spring5 框架 ---- AOP ---- 代码

    Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 ...

    spring-aop-5.2.0.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.2.0.RELEASE.jar; 赠送原API文档:spring-aop-5.2.0.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.2.0.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.2.0.RELEASE.pom;...

    spring-aop-5.3.10-API文档-中文版.zip

    赠送jar包:spring-aop-5.3.10.jar; 赠送原API文档:spring-aop-5.3.10-javadoc.jar; 赠送源代码:spring-aop-5.3.10-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.10.pom; 包含翻译后的API文档:spring...

    spring-aop-5.0.8.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.0.8.RELEASE.jar; 赠送原API文档:spring-aop-5.0.8.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.8.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.8.RELEASE.pom;...

    spring-aop-jar

    aopalliance.jar、spring-aop-4.1.6.RELEASE.jar、spring-aspects-4.1.6.RELEASE.jar

    spring-aop-3.2.5.RELEASE.jar ;spring-aop-3.2.5.jar

    spring-aop-3.2.5.RELEASE.jar

    spring-aop-2.0.8.jar

    spring-aop-2.0.8.jar

    spring-aop-5.3.12-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.12.jar; 赠送原API文档:spring-aop-5.3.12-javadoc.jar; 赠送源代码:spring-aop-5.3.12-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.12.pom; 包含翻译后的API文档:spring...

    spring-aop-5.1.3.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.1.3.RELEASE.jar; 赠送原API文档:spring-aop-5.1.3.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.1.3.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.1.3.RELEASE.pom;...

    spring-aop-4.0.4.RELEASE

    spring-aop-4.0.4.RELEASE 的jar包,亲测可用。。。。

    spring-aop-5.3.15-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.15.jar; 赠送原API文档:spring-aop-5.3.15-javadoc.jar; 赠送源代码:spring-aop-5.3.15-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.15.pom; 包含翻译后的API文档:spring...

    spring-aop-5.0.4.RELEASE.jar

    spring-aop-5.0.4.RELEASE.jar。

    spring,spring-aop-5.3.22.jar+aop+IDEA本地包

    spring-aop-5.3.22.jar Spring AOP provides an Alliance-compliant aspect-oriented programming implementation allowing you to define method interceptors and pointcuts to cleanly decouple code that ...

    spring-aop-3.2.0.RELEASE.jar

    spring-aop-3.2.0.RELEASE.jar,一个Spring中AOP的jar包

    spring-aop-5.3.15-API文档-中文版.zip

    赠送jar包:spring-aop-5.3.15.jar; 赠送原API文档:spring-aop-5.3.15-javadoc.jar; 赠送源代码:spring-aop-5.3.15-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.15.pom; 包含翻译后的API文档:spring...

    spring-aop-4.2.2.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-4.2.2.RELEASE.jar; 赠送原API文档:spring-aop-4.2.2.RELEASE-javadoc.jar; 赠送源代码:spring-aop-4.2.2.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-4.2.2.RELEASE.pom;...

    spring-aop-5.0.10.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.0.10.RELEASE.jar; 赠送原API文档:spring-aop-5.0.10.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.10.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.10.RELEASE....

Global site tag (gtag.js) - Google Analytics