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

Spring AOP 拦截器

阅读更多

最近由于一个项目需要对service层中的所有方法运行的情况(方法名、运行时间)和抛出的异常做一个拦截,所以趁机会对Spring的拦截器了解了下

拦截器的两个概念

Advice:通知,用于告知系统将有哪些新的行为。

Pointcut: 切入点,定义了通知应该在应用到那些连接点

 

演示实例

首先来看一个例子,(以下代码copy下来可以运行)

 

本实例主要实现程序对service层方法调用的时候,记录每个方法所花费的时间和抛出的异常。

 

1、所需引入的jar包括:

spring-2.5.6.jar

cglib-2.2.jar

commons-logging-1.1.1.jar

aspectjweaver-1.6.0.jar

 

2、编写业务逻辑代码

 

HelloService.java

 

package com.aop.demo.service;

 

public interface HelloService {

    public void sayHello(String name) throws Exception;

}

 

HelloServiceImpl.java

package com.aop.demo.service.impl;

 

import com.aop.demo.service.HelloService;

 

public class HelloServiceImpl implements HelloService {

    @Override

    public void sayHello(String name) throws Exception {

        //如果name为空,抛出异常

if(name == null || "".equals(name.trim())){

            throw new Exception("name can't be empty !");

        }

        System.out.println("hello "+name+" !");

    }

 

}

 

LogicService.java

 

package com.aop.demo.service;

 

public interface LogicService {

    public void doLogic() throws Exception;

}

 

LogicServiceImpl.java

package com.aop.demo.service.impl;

 

import com.aop.demo.service.LogicService;

 

public class LogicServiceImpl implements LogicService {

    @Override

    public void doLogic() throws Exception {       

        //sleep 3s

        Thread.sleep(3000);

        System.out.println("this is logic .");

    }

}

3、编写通知

  MethodBeforeAdvice,前置通知,该接口有一个唯一的方法before,在执行目标方法之前被调用

  AfterReturningAdvice,后置通知,该接口有一个唯一的方法after,在执行完目标方法之后被调用

  ThrowsAdvice,异常通知,实现afterThrowing,在目标方法抛出异常之后被调用

  MethodInterceptor,环绕通知,在一个方法执行之前和之后执行。 它使得通知有机会既在一个方法执行之前又在执行之后运行。并且,它可以决定这个方法在什么时候执行,如何执行,甚至是否执行。

 

 MethodAroundAdvice.java

package com.aop.demo.advice;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

import org.springframework.aop.MethodBeforeAdvice;

import org.springframework.aop.ThrowsAdvice;

public class MethodAroundAdvice implements MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice{   

    private long beforeRunTime;

    private long afterRunTime;

     

//service方法执行之前被调用

    @Override

    public void before(Method method, Object[] args, Object target)

            throws Throwable {

        //记录当前时间

        beforeRunTime = System.currentTimeMillis();

    }

 

    // service方法执行完之后被调用

    @Override

    public void afterReturning(Object arg0, Method method, Object[] args,

            Object target) throws Throwable {

        //记录当前时间

        afterRunTime = System.currentTimeMillis();

        //取得该方法运行所消耗的时间

        long durationTimes = afterRunTime - beforeRunTime;

        //类名

        String clazzName = target.getClass().getName();

        //方法名

        String methodName = method.getName();

System.out.println(clazzName+"."+methodName+" end running and spend

times is "+durationTimes);

    }

 

    //抛出Exception之后被调用

    public void afterThrowing(Method method, Object[] args, Object target,Exception ex) throws Throwable {

        String clazzName = target.getClass().getName();

        String methodName = method.getName();

        String exceptionClazz = ex.getClass().getName();

        String exceptionMessage = ex.getMessage();

        System.err.println(clazzName+"."+methodName+" have a error cause by:  \n"+exceptionClazz+", "+exceptionMessage);

    }

}

配置xml文件

applicationContext.xml

<?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"

            default-autowire="byName">

   

<aop:config>

<aop:advisor id="methodAroundAdviceAdvisor" advice-ref="methodAroundAdvice" pointcut="execution(* *..service.*Service.*(..))" />

</aop:config>

<!—通知类 -->   

<bean id="methodAroundAdvice" class="com.aop.demo.advice.MethodAroundAdvice"/>

<!-- 业务Bean -->

<bean id="logicService" class="com.aop.demo.service.impl.LogicServiceImpl" />

<bean id="helloService" class="com.aop.demo.service.impl.HelloServiceImpl" />

</beans>

 

编写测试类

 Test.java

package com.aop.demo;

 

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.aop.demo.service.HelloService;

import com.aop.demo.service.LogicService;

 

public class Test {

   public static void main(String[] args) {

      String config_xml = ".\\src\\applicationContext.xml";

      ApplicationContext ac = new FileSystemXmlApplicationContext(config_xml);

      try {

         LogicService logicService = (LogicService) ac.getBean("logicService");

         logicService.doLogic();

      //HelloService helloService = (HelloService) ac.getBean("helloService");

      //helloService.sayHello("");

      } catch (Exception e) {

         e.printStackTrace();

      }

   }

}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics