由于项目主管提出统计每个方法执行的具体时间,打印到日志以后方便分析问题。这个也是很常用的办法,但是我们调用的外部模块非常多,每个地方都加上一个时间统计就显得非常难看了。所以这个事情当然还是交给spring的AOP功能代理掉,就算那天不想统计时间了,清除这个功能也异常容易。下面给出一个小例子,非常的简单。
首先,给出一个Mouse的对象,他有几个基本的动作,我们就统计这些动作的具体执行时间。
- package log;
- public class Mouse {
- public String click(){
- System.out.println("click");
- return "clicked me";
- }
- public void move(){
- System.out.println("move");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
然后编写一个对于时间统计的类作为aspect。
- package log;
- import org.apache.log4j.Logger;
- import org.aspectj.lang.ProceedingJoinPoint;
- public class LogAspect {
- private Logger logger = Logger.getLogger(LogAspect.class);
- public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
- logger.warn("Beginning method: " + joinPoint.toLongString());
- long startTime = System.currentTimeMillis();
- Object result;
- try{
- result = joinPoint.proceed();
- }finally{
- logger.warn("Method invocation time: " + (System.currentTimeMillis() - startTime) + " ms.");
- }
- return result;
- }
- }
最关键的就是在配置文件声明横切面和具体执行类,注意这个bean必须在spring容器里面才行。
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
- <bean id="logAspect" class="log.LogAspect"/>
- <bean id="mouse" class="log.Mouse"/>
- <aop:config>
- <aop:pointcut id="logPointCut" expression="execution( * log.Mouse.*(..))" />
- <aop:aspect ref="logAspect">
- <aop:around pointcut-ref="logPointCut" method="invoke" />
- </aop:aspect>
- </aop:config>
- </beans>
最后给出执行的测试类
- package log;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class LogTest {
- public static ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app*.xml");
- public static void main(String[] args) {
- Mouse m = (Mouse) applicationContext.getBean("mouse");
- System.out.println(m.click());
- m.move();
- }
- }
这里再提下asm,这个横切进入的实现就是依靠asm的动态生成中间字节码,在生成字节码的动作中把具体的实现混入进去了。不得不赞叹一下~!
转载于:https://blog.51cto.com/passover/479386