Spring AOP基于注解的“零配置”方式实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring AOP基于注解的“零配置”方式实现相关的知识,希望对你有一定的参考价值。

  1. 为了在Spring中启动@AspectJ支持,需要在类加载路径下新增两个AspectJ库:aspectjweaver.jar和aspectjrt.jar。除此之外,Spring AOP还需要依赖一个aopalliance.jar包
  2. 定义一个类似ServiceAspect.java这样的切面bean:
  3.  1 package com.hyq.aop;
     2 
     3 import org.apache.commons.logging.Log;
     4 import org.apache.commons.logging.LogFactory;
     5 import org.aspectj.lang.JoinPoint;
     6 import org.aspectj.lang.ProceedingJoinPoint;
     7 import org.aspectj.lang.annotation.After;
     8 import org.aspectj.lang.annotation.AfterReturning;
     9 import org.aspectj.lang.annotation.AfterThrowing;
    10 import org.aspectj.lang.annotation.Around;
    11 import org.aspectj.lang.annotation.Aspect;
    12 import org.aspectj.lang.annotation.Before;
    13 import org.aspectj.lang.annotation.Pointcut;
    14 import org.springframework.stereotype.Component;
    15 
    16 /**
    17  * 系统服务组件Aspect切面Bean
    18  * @author Shenghany
    19  */
    20 //声明这是一个组件
    21 @Component
    22 //声明这是一个切面Bean
    23 @Aspect
    24 public class ServiceAspect {
    25 
    26     private final static Log log = LogFactory.getLog(ServiceAspect.class);
    27 
    28     //配置切入点,该方法无方法体,主要为方便同类中其他方法使用此处配置的切入点
    29     @Pointcut("execution(* com.hyq.aop..*(..))")
    30     public void aspect(){    }
    31 
    32     /*
    33      * 配置前置通知,使用在方法aspect()上注册的切入点
    34      * 同时接受JoinPoint切入点对象,可以没有该参数
    35      */
    36     @Before("aspect()")
    37     public void before(JoinPoint joinPoint){
    38         System.out.println("执行before.....");
    39     }
    40 
    41     //配置后置通知,使用在方法aspect()上注册的切入点
    42     @After("aspect()")
    43     public void after(JoinPoint joinPoint){
    44         System.out.println("执行after.....");
    45     }
    46 
    47     //配置环绕通知,使用在方法aspect()上注册的切入点
    48     @Around("aspect()")
    49     public void around(JoinPoint joinPoint){
    50         long start = System.currentTimeMillis();
    51         try {
    52             ((ProceedingJoinPoint) joinPoint).proceed();
    53             long end = System.currentTimeMillis();
    54             if(log.isInfoEnabled()){
    55                 log.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms!");
    56             }
    57         } catch (Throwable e) {
    58             long end = System.currentTimeMillis();
    59             if(log.isInfoEnabled()){
    60                 log.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms with exception : " + e.getMessage());
    61             }
    62         }
    63     }
    64 
    65     //配置后置返回通知,使用在方法aspect()上注册的切入点
    66     @AfterReturning("aspect()")
    67     public void afterReturn(JoinPoint joinPoint){
    68         if(log.isInfoEnabled()){
    69             log.info("afterReturn " + joinPoint);
    70         }
    71     }
    72 
    73     //配置抛出异常后通知,使用在方法aspect()上注册的切入点
    74     @AfterThrowing(pointcut="aspect()", throwing="ex")
    75     public void afterThrow(JoinPoint joinPoint, Exception ex){
    76         if(log.isInfoEnabled()){
    77             log.info("afterThrow " + joinPoint + "\t" + ex.getMessage());
    78         }
    79     }
    80 
    81 }

    3.定义一个业务组件,如:

  4.  1 package com.hyq.aop;
     2 
     3 import org.apache.commons.logging.Log;
     4 import org.apache.commons.logging.LogFactory;
     5 import org.springframework.stereotype.Component;
     6 @Component()
     7 public class UserService {
     8 
     9     private final static Log log = LogFactory.getLog(UserService.class);
    10     
    11     public User get(long id){
    12         if(log.isInfoEnabled()){
    13             log.info("getUser method . . .");
    14         }
    15         return new User();
    16     }
    17     
    18     public void save(User user){
    19         if(log.isInfoEnabled()){
    20             log.info("saveUser method . . .");
    21         }
    22     }
    23     
    24     public boolean delete(long id) throws Exception{
    25         if(log.isInfoEnabled()){
    26             log.info("delete method . . .");
    27             throw new Exception("spring aop ThrowAdvice演示");
    28         }
    29         return false;
    30     }
    31     
    32 }

    业务组件要用@Component()注解修饰

    4.在bean.xml中加入下面配置:

1 <!-- 激活组件扫描功能,在包com.hyq.aop及其子包下面自动扫描通过注解配置的组件 -->
2     <context:component-scan base-package="com.hyq.aop"/>
3     <!-- 激活自动代理功能 -->
4     <!-- <aop:aspectj-autoproxy proxy-target-class="true"/> -->
5     <aop:aspectj-autoproxy/>

 

以上是关于Spring AOP基于注解的“零配置”方式实现的主要内容,如果未能解决你的问题,请参考以下文章

Spring AOP基于@AspectJ注解的切面

Spring Aop实现方式(注解和Xml)

Spring Aop实现方式(注解和Xml)

SPRING学习(十九)--基于注解的AOP切面编程

spring学习5:基于注解实现spring的aop

Spring5学习笔记 — “AOP操作—AspectJ注解”