Maison > Java > javaDidacticiel > le corps du texte

SpringBoot intégré Spring aop exemple d'introduction

零下一度
Libérer: 2018-05-16 09:46:08
original
2643 Les gens l'ont consulté

Cet article présente principalement l'explication détaillée de l'intégration de SpringBoot de Spring AOP. L'éditeur pense que c'est assez bon, je vais donc le partager avec vous maintenant et le donner comme référence. Suivons l'éditeur et jetons un coup d'œil

Avant de commencer, nous ajoutons d'abord les packages jar requis au projet. Les nouvelles dépendances Maven sont les suivantes :

<dependency> 
  <groupId>org.springframework.boot</groupId> 
  <artifactId>spring-boot-starter-aop</artifactId> 
</dependency>
Copier après la connexion

Ensuite, nous entrons dans le vif du sujet. Les types de notification impliqués ici sont : pré-notification, notification post-finale, notification post-retour, notification post-exception et notification de bouclage. Examinons en détail comment ajouter ces notifications dans SpringBoot.

Nous créons d'abord une classe Aspect :

@Component 
@Aspect 
public class WebControllerAop { 
 
}
Copier après la connexion

Spécifiez le pointcut :

//匹配com.zkn.learnspringboot.web.controller包及其子包下的所有类的所有方法 
@Pointcut("execution(* com.zkn.learnspringboot.web.controller..*.*(..))") 
public void executeService(){ 
 
}
Copier après la connexion

Ensuite, nous créons une classe de traitement des requêtes Controller :

package com.zkn.learnspringboot.web.controller; 
 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RestController; 
 
/** 
 * Created by zkn on 2016/11/19. 
 */ 
@RestController 
@RequestMapping("/aop") 
public class AopTestController { 
 
}
Copier après la connexion

Pré-notification

Configurer la pré-notification :

/** 
 * 前置通知,方法调用前被调用 
 * @param joinPoint 
 */ 
@Before("executeService()") 
public void doBeforeAdvice(JoinPoint joinPoint){ 
  System.out.println("我是前置通知!!!"); 
  //获取目标方法的参数信息 
  Object[] obj = joinPoint.getArgs(); 
  //AOP代理类的信息 
  joinPoint.getThis(); 
  //代理的目标对象 
  joinPoint.getTarget(); 
  //用的最多 通知的签名 
  Signature signature = joinPoint.getSignature(); 
  //代理的是哪一个方法 
  System.out.println(signature.getName()); 
  //AOP代理类的名字 
  System.out.println(signature.getDeclaringTypeName()); 
  //AOP代理类的类(class)信息 
  signature.getDeclaringType(); 
  //获取RequestAttributes 
  RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); 
  //从获取RequestAttributes中获取HttpServletRequest的信息 
  HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST); 
  //如果要获取Session信息的话,可以这样写: 
  //HttpSession session = (HttpSession) requestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION); 
  Enumeration<String> enumeration = request.getParameterNames(); 
  Map<String,String> parameterMap = Maps.newHashMap(); 
  while (enumeration.hasMoreElements()){ 
    String parameter = enumeration.nextElement(); 
    parameterMap.put(parameter,request.getParameter(parameter)); 
  } 
  String str = JSON.toJSONString(parameterMap); 
  if(obj.length > 0) { 
    System.out.println("请求的参数信息为:"+str); 
  } 
}
Copier après la connexion

Remarque : JoinPoint et RequestContextHolder sont utilisés ici. Les informations de signature de la notification peuvent être obtenues via JoinPoint, telles que le nom de la méthode cible, les informations sur les paramètres de la méthode cible, etc. Obtenez des informations de demande et des informations de session via RequestContextHolder.

Ensuite, nous ajoutons une méthode de traitement des requêtes dans la classe Controller pour tester la pré-notification :

@RequestMapping("/testBeforeService.do") 
public String testBeforeService(String key,String value){ 
 
  return "key="+key+" value="+value; 
}
Copier après la connexion

Le résultat de l'interception de la pré-notification est le suivant :

Notification après retour

Le code pour configurer la notification après retour est le suivant :

/** 
 * 后置返回通知 
 * 这里需要注意的是: 
 *   如果参数中的第一个参数为JoinPoint,则第二个参数为返回值的信息 
 *   如果参数中的第一个参数不为JoinPoint,则第一个参数为returning中对应的参数 
 * returning 限定了只有目标方法返回值与通知方法相应参数类型时才能执行后置返回通知,否则不执行,对于returning对应的通知方法参数为Object类型将匹配任何目标返回值 
 * @param joinPoint 
 * @param keys 
 */ 
@AfterReturning(value = "execution(* com.zkn.learnspringboot.web.controller..*.*(..))",returning = "keys") 
public void doAfterReturningAdvice1(JoinPoint joinPoint,Object keys){ 
 
  System.out.println("第一个后置返回通知的返回值:"+keys); 
} 
 
@AfterReturning(value = "execution(* com.zkn.learnspringboot.web.controller..*.*(..))",returning = "keys",argNames = "keys") 
public void doAfterReturningAdvice2(String keys){ 
 
  System.out.println("第二个后置返回通知的返回值:"+keys); 
}
Copier après la connexion

Dans Contrôleur Ajoutez les informations de traitement de la demande de réponse pour tester la notification post-retour :

@RequestMapping("/testAfterReturning.do") 
public String testAfterReturning(String key){ 
 
  return "key=: "+key; 
} 
@RequestMapping("/testAfterReturning01.do") 
public Integer testAfterReturning01(Integer key){ 
 
  return key; 
}
Copier après la connexion

Lorsque la demande est envoyée : http://localhost:8001/aop/testAfterReturning.do?key=testsss&value=855sss, le résultat du traitement Comme le montre la figure :

Lorsque la requête est envoyée : http://localhost:8001/aop/testAfterReturning01.do?key=55553&value=855sss, le résultat du traitement est comme indiqué dans la figure Comme indiqué :

Notification d'exception de publication

La notification d'exception de publication est configuré comme suit :

/** 
 * 后置异常通知 
 * 定义一个名字,该名字用于匹配通知实现方法的一个参数名,当目标方法抛出异常返回后,将把目标方法抛出的异常传给通知方法; 
 * throwing 限定了只有目标方法抛出的异常与通知方法相应参数异常类型时才能执行后置异常通知,否则不执行, 
 *   对于throwing对应的通知方法参数为Throwable类型将匹配任何异常。 
 * @param joinPoint 
 * @param exception 
 */ 
@AfterThrowing(value = "executeService()",throwing = "exception") 
public void doAfterThrowingAdvice(JoinPoint joinPoint,Throwable exception){ 
  //目标方法名: 
  System.out.println(joinPoint.getSignature().getName()); 
  if(exception instanceof NullPointerException){ 
    System.out.println("发生了空指针异常!!!!!"); 
  } 
}
Copier après la connexion

Configurer la classe de traitement des demandes de réponse dans le contrôleur :

@RequestMapping("/testAfterThrowing.do") 
public String testAfterThrowing(String key){ 
 
  throw new NullPointerException(); 
}
Copier après la connexion

Le résultat du traitement de la méthode de notification post-exception est le suivant :

Notification post-finale

La notification post-finale est configurée comme suit :

/** 
 * 后置最终通知(目标方法只要执行完了就会执行后置通知方法) 
 * @param joinPoint 
 */ 
@After("executeService()") 
public void doAfterAdvice(JoinPoint joinPoint){ 
 
  System.out.println("后置通知执行了!!!!"); 
}
Copier après la connexion

Classe de contrôleur configure la classe de traitement de requête correspondante :

@RequestMapping("/testAfter.do") 
public String testAfter(String key){ 
 
  throw new NullPointerException(); 
} 
@RequestMapping("/testAfter02.do") 
public String testAfter02(String key){ 
 
  return key; 
}
Copier après la connexion

Lorsque la requête est envoyée : http://localhost:8001/aop/testAfter.do?key=55553&value=855sss

Lorsque la requête est envoyée : http ://localhost:8001/aop/testAfter02.do?key=55553&value=855sss

surround notification

La méthode de configuration de la notification surround est la suivante :

/** 
 * 环绕通知: 
 *  环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。 
 *  环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型 
 */ 
@Around("execution(* com.zkn.learnspringboot.web.controller..*.testAround*(..))") 
public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){ 
  System.out.println("环绕通知的目标方法名:"+proceedingJoinPoint.getSignature().getName()); 
  try { 
    Object obj = proceedingJoinPoint.proceed(); 
    return obj; 
  } catch (Throwable throwable) { 
    throwable.printStackTrace(); 
  } 
  return null; 
}
Copier après la connexion

La classe de traitement des requêtes correspondant au Contrôleur est la suivante :

@RequestMapping("/testAroundService.do") 
public String testAroundService(String key){ 
 
  return "环绕通知:"+key; 
}
Copier après la connexion

Lors de l'envoi de la demande : http://localhost:8001/aop/testAroundService do?key=55553

Lors de l'envoi de la demande à : http:/. /localhost:8001/aop/testAfter02.do?key=55553&value=855sss, la notification environnante ne respecte pas les règles d'activation, donc les conseils environnants ne seront pas exécutés.

Le code de configuration AOP complet est le suivant :

package com.zkn.learnspringboot.aop; 
 
import com.alibaba.fastjson.JSON; 
import com.google.common.collect.Maps; 
import org.aspectj.lang.JoinPoint; 
import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.Signature; 
import org.aspectj.lang.annotation.*; 
import org.springframework.stereotype.Component; 
import org.springframework.web.context.request.RequestAttributes; 
import org.springframework.web.context.request.RequestContextHolder; 
 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpSession; 
import java.util.Enumeration; 
import java.util.Map; 
 
/** 
 * Created by zkn on 2016/11/18. 
 */ 
@Component 
@Aspect 
public class WebControllerAop { 
 
  //匹配com.zkn.learnspringboot.web.controller包及其子包下的所有类的所有方法 
  @Pointcut("execution(* com.zkn.learnspringboot.web.controller..*.*(..))") 
  public void executeService(){ 
 
  } 
 
  /** 
   * 前置通知,方法调用前被调用 
   * @param joinPoint 
   */ 
  @Before("executeService()") 
  public void doBeforeAdvice(JoinPoint joinPoint){ 
    System.out.println("我是前置通知!!!"); 
    //获取目标方法的参数信息 
    Object[] obj = joinPoint.getArgs(); 
    //AOP代理类的信息 
    joinPoint.getThis(); 
    //代理的目标对象 
    joinPoint.getTarget(); 
    //用的最多 通知的签名 
    Signature signature = joinPoint.getSignature(); 
    //代理的是哪一个方法 
    System.out.println(signature.getName()); 
    //AOP代理类的名字 
    System.out.println(signature.getDeclaringTypeName()); 
    //AOP代理类的类(class)信息 
    signature.getDeclaringType(); 
    //获取RequestAttributes 
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); 
    //从获取RequestAttributes中获取HttpServletRequest的信息 
    HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST); 
    //如果要获取Session信息的话,可以这样写: 
    //HttpSession session = (HttpSession) requestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION); 
    Enumeration<String> enumeration = request.getParameterNames(); 
    Map<String,String> parameterMap = Maps.newHashMap(); 
    while (enumeration.hasMoreElements()){ 
      String parameter = enumeration.nextElement(); 
      parameterMap.put(parameter,request.getParameter(parameter)); 
    } 
    String str = JSON.toJSONString(parameterMap); 
    if(obj.length > 0) { 
      System.out.println("请求的参数信息为:"+str); 
    } 
  } 
 
  /** 
   * 后置返回通知 
   * 这里需要注意的是: 
   *   如果参数中的第一个参数为JoinPoint,则第二个参数为返回值的信息 
   *   如果参数中的第一个参数不为JoinPoint,则第一个参数为returning中对应的参数 
   * returning 限定了只有目标方法返回值与通知方法相应参数类型时才能执行后置返回通知,否则不执行,对于returning对应的通知方法参数为Object类型将匹配任何目标返回值 
   * @param joinPoint 
   * @param keys 
   */ 
  @AfterReturning(value = "execution(* com.zkn.learnspringboot.web.controller..*.*(..))",returning = "keys") 
  public void doAfterReturningAdvice1(JoinPoint joinPoint,Object keys){ 
 
    System.out.println("第一个后置返回通知的返回值:"+keys); 
  } 
 
  @AfterReturning(value = "execution(* com.zkn.learnspringboot.web.controller..*.*(..))",returning = "keys",argNames = "keys") 
  public void doAfterReturningAdvice2(String keys){ 
 
    System.out.println("第二个后置返回通知的返回值:"+keys); 
  } 
 
  /** 
   * 后置异常通知 
   * 定义一个名字,该名字用于匹配通知实现方法的一个参数名,当目标方法抛出异常返回后,将把目标方法抛出的异常传给通知方法; 
   * throwing 限定了只有目标方法抛出的异常与通知方法相应参数异常类型时才能执行后置异常通知,否则不执行, 
   *   对于throwing对应的通知方法参数为Throwable类型将匹配任何异常。 
   * @param joinPoint 
   * @param exception 
   */ 
  @AfterThrowing(value = "executeService()",throwing = "exception") 
  public void doAfterThrowingAdvice(JoinPoint joinPoint,Throwable exception){ 
    //目标方法名: 
    System.out.println(joinPoint.getSignature().getName()); 
    if(exception instanceof NullPointerException){ 
      System.out.println("发生了空指针异常!!!!!"); 
    } 
  } 
 
  /** 
   * 后置最终通知(目标方法只要执行完了就会执行后置通知方法) 
   * @param joinPoint 
   */ 
  @After("executeService()") 
  public void doAfterAdvice(JoinPoint joinPoint){ 
 
    System.out.println("后置通知执行了!!!!"); 
  } 
 
  /** 
   * 环绕通知: 
   *  环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。 
   *  环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型 
   */ 
  @Around("execution(* com.zkn.learnspringboot.web.controller..*.testAround*(..))") 
  public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){ 
    System.out.println("环绕通知的目标方法名:"+proceedingJoinPoint.getSignature().getName()); 
    try {//obj之前可以写目标方法执行前的逻辑 
      Object obj = proceedingJoinPoint.proceed();//调用执行目标方法 
      return obj; 
    } catch (Throwable throwable) { 
      throwable.printStackTrace(); 
    } 
    return null; 
  } 
}
Copier après la connexion

Le code complet de la classe du contrôleur est le suivant :

package com.zkn.learnspringboot.web.controller; 
 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RestController; 
 
/** 
 * Created by zkn on 2016/11/19. 
 */ 
@RestController 
@RequestMapping("/aop") 
public class AopTestController { 
 
  @RequestMapping("/testBeforeService.do") 
  public String testBeforeService(String key,String value){ 
 
    return "key="+key+" value="+value; 
  } 
  @RequestMapping("/testAfterReturning.do") 
  public String testAfterReturning(String key){ 
 
    return "key=: "+key; 
  } 
  @RequestMapping("/testAfterReturning01.do") 
  public Integer testAfterReturning01(Integer key){ 
 
    return key; 
  } 
  @RequestMapping("/testAfterThrowing.do") 
  public String testAfterThrowing(String key){ 
 
    throw new NullPointerException(); 
  } 
  @RequestMapping("/testAfter.do") 
  public String testAfter(String key){ 
 
    throw new NullPointerException(); 
  } 
  @RequestMapping("/testAfter02.do") 
  public String testAfter02(String key){ 
 
    return key; 
  } 
  @RequestMapping("/testAroundService.do") 
  public String testAroundService(String key){ 
 
    return "环绕通知:"+key; 
  } 
}
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal