Spring AOP的注解实例(2)

*环绕通知(Around advice) :包围一个连接点的通知,类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为,也可以选择不执行。

*抛出异常后通知(After throwing advice) : 在方法抛出异常退出时执行的通知。

定义一个接口,并编写实现类:

public interface UserService {
        public void addUser(String userName, String password);
    }

@Service("userService")
    public class UserServiceImpl implements UserService {

@Override
        public void addUser(String userName, String password) {     
            System.out.println("--------------User addUser-------------");
      }


  }

定义切面类

@Aspect//定义切面
@Component//声明这是一个组件
public class Interceptor {

private final static Log log = LogFactory.getLog(Interceptor.class);
   
    /**
    * 这句话是方法切入点
    * 1 execution (* com.wangku.spring.service.impl..*.*(..))
    * 2 execution : 表示执行
    * 3 第一个*号 : 表示返回值类型, *可以是任意类型
    * 4 com.spring.service.impl : 代表扫描的包
    * 5 .. : 代表其底下的子包也进行拦截 
    * 6 第二个*号 : 代表对哪个类进行拦截,*代表所有类 
    * 7 第三个*号 : 代表方法  *代表任意方法
    * 8 (..) : 代表方法的参数有无都可以
    */
    //配置切入点,该方法无方法体,主要为方便同类中其他方法使用此处配置的切入点
    @Pointcut("execution (* com.gcx.service.impl..*.*(..))")
    private void aspect() {
            System.out.println("============进入aspect方法==============");
    }
           
    //配置环绕通知,使用在方法aspect()上注册的切入点
    @Around("aspect()")
    public void around(JoinPoint joinPoint){
        long start = System.currentTimeMillis();
        try {
            ((ProceedingJoinPoint) joinPoint).proceed();
            long end = System.currentTimeMillis();
            if(log.isInfoEnabled()){
                log.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms!");//这里顺便记录下执行速度,可以作为监控
            }
        } catch (Throwable e) {
            long end = System.currentTimeMillis();
            if(log.isInfoEnabled()){
                log.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms with exception : " + e.getMessage());
            }
        }
    }
    //前置通知等可以没有JoinPoint参数
    @Before("aspect()")
    public void doBefore(JoinPoint joinPoint) {
        System.out.println("==========执行前置通知===============");
        if(log.isInfoEnabled()){
            log.info("before " + joinPoint);
        }
    }     
    //配置后置通知,使用在方法aspect()上注册的切入点
    @After("aspect()")
    public void doAfter(JoinPoint joinPoint) {
        System.out.println("===========执行后置通知==============");
        if(log.isInfoEnabled()){
            log.info("after " + joinPoint);
        }
    } 
    //配置后置返回通知,使用在方法aspect()上注册的切入点
    @AfterReturning("aspect()")
    public void afterReturn(JoinPoint joinPoint){

System.out.println("===========执行后置返回通知==============");
            if(log.isInfoEnabled()){
                log.info("afterReturn " + joinPoint);
            }
    } 
    //配置抛出异常后通知,使用在方法aspect()上注册的切入点
    @AfterThrowing(pointcut="aspect()", throwing="ex")
    public void afterThrow(JoinPoint joinPoint, Exception ex){
            if(log.isInfoEnabled()){
                log.info("afterThrow " + joinPoint + "\t" + ex.getMessage());
            }
    }   
}
测试类

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/146d56c6becdce86642cb13be158c60b.html