SpringBoot en utilisant la technologie à base AOP pour parvenir à une gestion opérationnelle du journal

Tout d'abord, le concept de base

section de ressort peut être appliquée à cinq types de notification:

Pré-notification (Avant): appel avis avant que la méthode cible est appelée

Après des conseils de retour (après): la notification d'appel après la méthode de cible d'achèvement (soit la sortie normale ou anormale)

notification de retour (après le retour): notification appel après l'exécution réussie de la méthode cible

notification d'exception (après lancement): notification d'appel lorsque la méthode cible génère une exception

Autour des conseils (autour): la mise en uvre de la coutume emballé après la méthode de notification à notifier, avant que la méthode est informé des appels et le comportement d'appel

L'ordre serait:

application de base ultérieure, volonté autour des conseils , avant de conseils , Après le retour des conseils , Retour à Nouvelles , anormale avis En vue d'atteindre, et démontre son ordre d'exécution.

En second lieu, l'application de base

revendications Indication

Vous pouvez copier le code ci-dessous, effectuer une vérification de la séquence ci-dessus.

@Aspect

Public class Test {

 int statique privé étape = 0;

 @Pointcut ( "@ annotation (com.chenyanwu.erp.erpframework.annotation.Log)") // l'expression pointcut

 opération private void () {}

 @Before (opération "()")

 doBeforeTask () {publique vide

 System.out.println (++ étape + "pré-notification");

 }

 @After (opération "()")

 doAfterTask () {publique vide

 System.out.println (++ + étape "notification arrière");

 }

 @AfterReturning (pointcut = "opération ()", retour = "retVal")

 public void doAfterReturnningTask (Object retVal) {

 System.out.println (++ + étape "notification de retour, la valeur de retour:" + retVal.toString ());

 }

 @AfterThrowing (pointcut = "opération ()", lancer = "ex")

 doAfterThrowingTask public void (Exception ex) {

 System.out.println (++ étape + "notification d'exception, les informations d'exception est:" + ex.getMessage ());

 }

 / **

 * Autour de types de conseils des paramètres nécessaires pour effectuer ProceedingJoinPoint

 * Autour des conseils est similaire au processus de procurations dynamiques types ProceedingJoinPoint de paramètres peut décider si la méthode cible

 * Et notification entourant doit revenir, à savoir la valeur de retour de la valeur de retour de la cible

 * /

 // @ Around ( "opération ()")

 doAroundTask public Object (ProceedingJoinPoint PJP) {

 Chaîne methodname = pjp.getSignature () getName () .;

 Objet résultat = null;

 try {

 // Prénotification

 System.out.println ( "méthode cible" + methodname + "paramètre start" + Arrays.asList (pjp.getArgs ()));

 // exécuter la méthode cible

 entraîner = pjp.proceed ();

 // renvoie un avis

 System.out.println ( "méthode objective" + methodname + "réussit, le retour" + résultat);

 } Catch (e Throwable) {

 // notification d'exception

 System.out.println ( "méthode objective" + methodname + "renvoie une exception:" + e.getMessage ());

 }

 // après avis

 System.out.println ( "méthode cible" + methodname + "End");

 résultat retour;

 }

}

Quel est le point d'entrée à noter: l'expression @Pointcut

Format:

exécution (modificateurs motif? ret de type-modèle de type déclarant motif? nom-motif (param-motif) jette motif?)

Chaque modèle entre parenthèses indiquent les éléments suivants:

  • modificateur de match (modificateur de modèle?)
  • match de valeur de retour (RET-type motif) * peut représenter une valeur de retour, et ainsi le chemin complet de la classe
  • match Classpath (-modèle déclarant type?)
  • Correspondant nom de la méthode (nom-motif) ou peut représenter tous les noms de méthode de tous les procédés représentatifs au début du jeu,
  • paramètres assortis ((param-motif)) peut spécifier un type particulier de paramètres, parmi la pluralité de paramètres « » séparés, chaque paramètre peut être utilisé « » pour représenter - correspondre à tout type de paramètres, tels que (String) indique une correspondance le procédé paramètre de chaîne, (, String) représente le processus d'appariement a deux paramètres, le premier paramètre peut être tout type, et le second paramètre est le type de chaîne, peut être (...) représente zéro ou plusieurs paramètre arbitraire
  • concordance des types d'exception (jette motif?)
  • Qui a suivi derrière « ? » Est facultatif

exemple:

1) l'exécution (* (...))

// moyens correspondent à toutes les méthodes

2) exécution (public * com. Savage.service.UserService. (...))

// indique une com.savage.server.UserService match toutes les méthodes publiques

3) exécution (* com.savage.server .... (...))

// Toutes les méthodes représentées dans les sous-paquets et les paquets correspondants com.savage.server

En troisième lieu, le combat de gestion des logs

Avec la compréhension ci-dessus de l'application de base, maintenant nous collons directement le code:

1, paquet de pot dépendent

 org.springframework.boot

 printemps-boot-démarreur-aop

2, annotations personnalisées

@Target (ElementType.METHOD)

@Retention (RetentionPolicy.RUNTIME)

@interface publique Log {

 Valeur de chaîne () par défaut « »;

}

3, mettre en uvre l'aspect

@Aspect

@Order (5)

@component

public class {LogAspect

 enregistreur privé Logger = LoggerFactory.getLogger (LogAspect.class);

 @Autowired

 privé ErpLogService LogService;

 @Autowired

 ObjectMapper objectMapper;

 privé ThreadLocal startTime = new ThreadLocal ();

 @Pointcut ( "annotation @ (com.chenyanwu.erp.erpframework.annotation.Log)")

 pointcut public void () {

 }

 / **

 * Pré-notification, à intercepter avant l'opération de couche contrôleur

 *

 * @Param point d'entrée JoinPoint

 * /

 @Before ( "pointcut ()")

 doBefore public void (JoinPoint JoinPoint) {

 // Obtenez le temps d'appel en cours

 startTime.set (new Date ());

 }

 / **

 * Rendement normal

 *

 * @Param point d'entrée JoinPoint

 * @param RVT résultats normaux

 * /

 @AfterReturning (pointcut = "pointcut ()", retour = "RVT")

 doAfter public void (JoinPoint JoinPoint, objet RVT) throws Exception {

 handleLog (Joinpoint, null, RVT);

 }

 / **

 * Interception des messages d'exception

 *

 * @Param JoinPoint

 * @Param e

 * /

 @AfterThrowing (pointcut = "pointcut ()", lancer = "e")

 doAfter public void (JoinPoint JoinPoint, Exception e) throws Exception {

 handleLog (Joinpoint, e, null);

 }

 @Async

 handleLog private void (finale JoinPoint JoinPoint, exception finale e, objet RVT) throws Exception {

 // recueillir les commentaires

 Procédé Method = getMethod (Joinpoint);

 Connexion log = getAnnotationLog (méthode);

 if (log == null) {

 retour;

 }

 Date maintenant = new Date ();

 // manipuler la table du journal de base de données

 ErpLog erpLog = new ErpLog ();

 erpLog.setErrorCode (0);

 erpLog.setIsDeleted (0);

 // information de demande

 HttpServletRequest request = ToolUtil.getRequest ();

 erpLog.setType (ToolUtil.isAjaxRequest (requête) "demande Ajax": "demande générale");

 erpLog.setTitle (log.value ());

 erpLog.setHost (request.getRemoteHost ());

 erpLog.setUri (request.getRequestURI () toString ().);

// erpLog.setHeader (request.getHeader (HttpHeaders.USER_AGENT));

 erpLog.setHttpMethod (request.getMethod ());

 erpLog.setClassMethod (joinPoint.getSignature () getDeclaringTypeName () + + joinPoint.getSignature () getName (). "".);

 Méthode de demande de valeur du paramètre

 Objet args = joinPoint.getArgs ();

 demande Méthodes Nom du paramètre

 LocalVariableTableParameterNameDiscoverer u

 = New LocalVariableTableParameterNameDiscoverer ();

 Chaîne paramNames = u.getParameterNames (méthode);

 if (args! = null && paramNames! = null) {

 StringBuilder params = new StringBuilder ();

 params = handleParams (params, args, Arrays.asList (paramNames));

 erpLog.setParams (params.toString ());

 }

 Chaîne retString = JsonUtil.bean2Json (RVT);

 erpLog.setResponseValue (? retString.length ()> 5000 JsonUtil.bean2Json ( "données de paramètres de demande ne montre pas trop"): retString);

 if (e! = null) {

 erpLog.setErrorCode (1);

 erpLog.setErrorMessage (e.getMessage ());

 }

 Date stime = startTime.get ();

 erpLog.setStartTime (stime);

 erpLog.setEndTime (maintenant);

 erpLog.setExecuteTime (now.getTime () - stime.getTime ());

 erpLog.setUsername (MySysUser.loginName ());

 HashMap browserMap = ToolUtil.getOsAndBrowserInfo (demande);

 erpLog.setOperatingSystem (browserMap.get ( "os"));

 erpLog.setBrower (browserMap.get ( "navigateur"));

 erpLog.setId (IdUtil.simpleUUID ());

 logService.insertSelective (erpLog);

 }

 / **

 * L'existence de notes, si vous obtenez

 * /

 Connexion privé getAnnotationLog (méthode Method) {

 si (méthode! = null) {

 retour method.getAnnotation (Log.class);

 }

 return null;

 }

 Méthode privée getMethod (JoinPoint JoinPoint) {

 signature Signature = joinPoint.getSignature ();

 MethodSignature signature methodSignature = (MethodSignature);

 Procédé Method = methodSignature.getMethod ();

 si (méthode! = null) {

 Procédé de retour;

 }

 return null;

 }

 handleParams de StringBuilder privées (StringBuilder params, objet args, Liste paramNames) lancers francs JsonProcessingException {

 pour (int i = 0; i

BES exprès chargé de 13 tonnes a répondu « double 11 » feu de camion de livraison: et le paiement a été réédité produits
Précédent
réseau commercial sérieux marché aux légumes rouge, nous avons constaté que ce n'est pas aussi simple que des images de bonne mine
Prochain
Journée des pompiers et « la moitié »
Zhejiang et ouvert « le long du chemin » Fòrum de réflexion tenue à Hangzhou
Les projets de haute technologie chinois par les scientifiques occidentaux accordent plus d'attention aux médias étrangers: la Chine est très clairvoyant
Nouvel hôtel | Hoshino Resorts au Japon a ouvert une ferme construite hôtel de villégiature
combustion Supersonic! Alipay art documentaire double 11 « une bataille » de première mondiale exclusive
Shanghai plus marché de nuit de style occidental est de retour! Promenez-vous manger complètement Raiders, en jouant avec le week-end
Votre courrier à double onze et brûlé à grande vitesse? Rookie Inn n'a pas envoyé ce message
Top la terreur de bidon dans quelle mesure? La vérité est révélée, le fait que les gens ne peuvent pas croire
Journée internationale pour la tolérance | tolérant envers les autres, doit être eu large
Kunqu « Pavillon de Pivoine » trouver des amis en Europe, « de Du est Sleeping Beauty de la Chine »
Écoutez les voix des utilisateurs a atteint la résonance émotionnelle: « user-centric » est la FAW - la formule gagnante de Volkswagen Audi
! imprévisible Bas de l'Est renversé en sixième ouest, Jazz 3 Coupe vide 72 minutes à court de succès