Spring AOP实践(二)编程篇

7 篇文章 0 订阅

上一篇泛泛的讲了很多关于AOP和代理的理解,实现原理,动态和静态代理的比较,如何选择等。这篇讲到如何实践。
Spring的AOP很容易使用,查看Spring文档即可。
http://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#aop

我这里要用Spring AOP解决下面几个问题,第一,我想在系统入口,也就是RESTful的Controller的每个方法调用前和调用后分别答应一句log----“进入xyz方法”,“离开xyz方法”。第二个想要实现的功能是,我想在每个DAO的方法执行完成后知道它的执行时间---打印执行时间,这对优化性能很有帮助。第三个想要实现的功能是,我要在所有service类的方法发生异常时发送一封邮件给管理员。

这分别要用到这些advice类型:第一个功能,可以用两个方法来实现,一个Before advice,一个After advice;第二个功能可以用Around advice;第三个功能可以用After throwing advice;

这篇不想总结知识,只想贴代码,所以不解释名词,下一篇再做总结,其实Spring参考文档都说的很清楚也很好理解。

首先是需要引入的jar包,我引入了以下两个包:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.9</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.9</version>
</dependency>
然后,如果配置Spring AOP在代码中的使用,enable AOP support

我使用的是java 源码配置的方式,需要在一个声明了@Configuration的类上声明@EnableAspectJAutoProxy,这里我新建了一个类:

@Configuration
@EnableAspectJAutoProxy
public class CommonConfiguration {

}
然后就是定义相关的Aspect,这里为每个要解决的问题定义一个Aspect类,第一个问题的解决:

注意如果是用的自动扫描Bean的配置,一定要有@Component,如果手动配置Bean则只需要@Aspect

@Aspect
@Component 
public class ControllerLogAspect {

	private static Logger logger = Logger.getLogger(RentingRestController.class);
	
	
	@Before("execution(* com.viking.renting.rest.api.*.*(..))")
	public void logMethodStart(JoinPoint point) {
		String methodName = point.getSignature().getName();
		logger.info("======= entering method " + methodName + "========");
	}
	
	@After("execution(* com.viking.renting.rest.api.*.*(..))")
	public void logMethodEnd(JoinPoint point) {
		String methodName = point.getSignature().getName();
		logger.info("======= leaving method " + methodName + "========");
	}
}

第二个问题的解决:

@Aspect
@Component 
public class DaoLogAspect {
	
	private static Logger logger = Logger.getRootLogger();
	
	@Around("execution(* com.viking.renting.dao.*.*(..))")
	public Object calculateMethodCostTime(ProceedingJoinPoint pjp) throws Throwable {
		Object target = pjp.getTarget();
		String methodName = pjp.getSignature().getName();
		logger.info("*** entering " + target.getClass().getName() + ": " + methodName);
		long startTime = System.currentTimeMillis();
		Object retVal = pjp.proceed();
		logger.info("*** leaving " + target.getClass().getName() + ": " + methodName + ", cost time:" + (System.currentTimeMillis() - startTime));
        return retVal;
	}
}
第三个问题的解决:

@Aspect
@Component 
public class ServiceExceptionAspect {
	
	private static Logger logger = Logger.getRootLogger();

	@AfterThrowing("execution(* com.viking.renting.service.*.*(..))")
	public void sendEmailWhenException(JoinPoint point) {
		Object target = point.getTarget();
		String methodName = point.getSignature().getName();
		logger.error("exception happened in:" + target.getClass().getName() + ":" + methodName +" sending email to admin.");
	}
}
代码中用到的知识点将在下一篇总结。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值