首先是几个概念:连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、切面(Aspect)

另外也要使用到注解。

需求:通过注解定义LogEnable。然后程序运行能够识别定义了LogEnable注解的方法记录日志。

1.定义注解

package cn.duanjt.util;

import java.lang.annotation.*;

/**
* 记录日志的注解类
* @author 段江涛
* @date 2018-11-08
*/
@Target(ElementType.METHOD)//表示用于标识方法
@Retention(RetentionPolicy.RUNTIME)//表示运行时保留
public @interface LogEnable {
/**
* 主要是标志日志的描述信息
* @return
*/
String note() default "";
}

2.定义需要监听的类和方法

package cn.duanjt.service;

import org.springframework.stereotype.Service;

import cn.duanjt.Pojo.Student;
import cn.duanjt.util.LogEnable; @Service
public class StudentService {
//定义注解,然后描述当前方法的作用
@LogEnable(note="获取学生信息")
public Student getStudent(int id) {
if (id == 0) {
throw new RuntimeException("编码不能为0");
}
Student stu = new Student();
stu.setId(id);
stu.setName("zhangsan");
stu.setAddr("重庆");
return stu;
} //未定义注解,将不会被监听
public int getId(int id) {
return id + 1;
}
}

3.定义切面,记录日志

package cn.duanjt.util;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component; @Aspect
@Component
public class LogHelper {
// 没有单独定义切点,直接在环绕方法里面处理[包cn.duanjt.service下面的所有类下面的所有方法,同时包含LogEnable注解的将被监听]
@Around("execution(* cn.duanjt.service.*.*(..)) && @annotation(LogEnable)")
public Object around(ProceedingJoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
long time = System.currentTimeMillis(); //记录开始时间
String className = point.getTarget().getClass().getName(); // 类名
String method = className + "." + signature.getName(); //方法名
Object[] args = point.getArgs(); // 参数 LogEnable logEnable= signature.getMethod().getAnnotation(LogEnable.class);
String logNote=logEnable.note(); //日志信息
try {
Object result = point.proceed();
System.out.println("方法名:" + method);
System.out.println("参数:" + StringUtils.join(args));
System.out.println("返回值:" + result.toString());
System.out.println("日志功能:" + logNote);
System.out.println("耗时:" + (System.currentTimeMillis() - time) + "毫秒");
System.out.println("-----------------------");
return result;
} catch (Exception e) {
System.out.println("方法名1:" + method);
System.out.println("参数:" + StringUtils.join(args));
System.out.println("日志功能:" + logNote);
System.out.println("异常信息:" + e.getMessage());
System.out.println("耗时:" + (System.currentTimeMillis() - time) + "毫秒");
System.out.println("-----------------------");
return null;
} catch (Throwable e) {
return null;
} }
}

4.在主程序上要加上注解@EnableAspectJAutoProxy。我这里使用的是springboot,如下:

package cn.duanjt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @SpringBootApplication
@ComponentScan("cn.duanjt")
@EnableAspectJAutoProxy //表示启用AOP
public class ServerDemoApplication { public static void main(String[] args) {
SpringApplication.run(ServerDemoApplication.class, args);
}
}

最后,运行结果如下:

方法名:cn.duanjt.service.StudentService.getStudent
参数:
返回值:Student [id=, name=zhangsan, addr=重庆]
日志功能:获取学生信息
耗时:毫秒
-----------------------

注意:

1. @EnableAspectJAutoProxy用于开启全局的AOP

2. LogHelper类上面的@Aspect和@Component是必须的,前者用于标注是切面,后者用于将对象注入到spring容器

3. 切面表达式@Around("execution(* cn.duanjt.service.*.*(..)) && @annotation(LogEnable)").一定需要execution。详细的可以下去再了解

spring aop通过注解实现日志记录的更多相关文章

  1. 利用Spring AOP自定义注解解决日志和签名校验

    转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...

  2. spring AOP自定义注解 实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

  3. (转)利用Spring AOP自定义注解解决日志和签名校验

    一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: ...

  4. 运用Spring Aop,一个注解实现日志记录

    运用Spring Aop,一个注解实现日志记录 1. 介绍 我们都知道Spring框架的两大特性分别是 IOC (控制反转)和 AOP (面向切面),这个是每一个Spring学习视频里面一开始都会提到 ...

  5. spring AOP自定义注解方式实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

  6. Spring Boot 2.X(八):Spring AOP 实现简单的日志切面

    AOP 1.什么是 AOP ? AOP 的全称为 Aspect Oriented Programming,译为面向切面编程,是通过预编译方式和运行期动态代理实现核心业务逻辑之外的横切行为的统一维护的一 ...

  7. spring aop 使用注解方式总结

    spring aop的注解方式:和xml的配置方式略有区别,详细如下: 1.首先还是建立需要的切面类:切面类里面定义好切点配置,以及所有的需要实现的通知方法. /** * */ package com ...

  8. Spring aop+自定义注解统一记录用户行为日志

    写在前面 本文不涉及过多的Spring aop基本概念以及基本用法介绍,以实际场景使用为主. 场景 我们通常有这样一个需求:打印后台接口请求的具体参数,打印接口请求的最终响应结果,以及记录哪个用户在什 ...

  9. Spring AOP使用注解记录用户操作日志

    最后一个方法:核心的日志记录方法 package com.migu.cm.aspect; import com.alibaba.fastjson.JSON; import com.migu.cm.do ...

随机推荐

  1. 07: mysql锁和事物隔离

    MySQL其他篇 目录: 1.1 MySQL中的事物 1.2 mysql中锁 1.1 MySQL中的事物返回顶部 1.InnoDB事务原理 1. 事务(Transaction)是数据库区别于文件系统的 ...

  2. 06: mysql索引查找原理及调优

    MySQL其他篇 目录: 1.1 常见查找方法举例 1.2 索引数据结构设相关的计算机原理 1.3 MyISAM实现索引 1.4 InnoDB索引实现 1.5 索引使用策略 1.1 常见查找方法举例返 ...

  3. curl 用法总结

    curl -g -k --noproxy '*' -s -o /dev/null -w '%{http_code}' http://172.25.112.34/identity/v3 KSURL=ht ...

  4. linux command wrap

    $ cat tmux-attach ] ; then tmux ls else tmux attach -t $ fi $ cat /usr/bin/cscope-go.sh #!/bin/bash ...

  5. java常用类-String类

    * 字符串:就是由多个字符组成的一串数据.也可以看成是一个字符数组. * 通过查看API,我们可以知道 * A:字符串字面值"abc"也可以看成是一个字符串对象. * B:字符串是 ...

  6. UVa 12099 The Bookcase - 动态规划

    题目大意 给定一些书,每个书有一个高度和宽度,然后将它们放到一个三层的书架里(要求每一层都不为空).定义书架的大小为每层最大的高度和 乘 每层宽度和的最大值.求最小的书架大小. 显然动态规划(直觉,没 ...

  7. dubbo接口FindMemberInfoTest思路整合

    package com.yzb.user_center; /** * @Created by IntelliJ IDEA. * @Author tk * @Date 2018/7/31 * @Time ...

  8. python ---24 正则表达式 re模块

    一.正则表达式 1.字符组 ① [abc] 匹配a或b或c ②  [a-z] 匹配a到z之间的所有字⺟ [0-9]匹配所有阿拉伯数字 2.元字符 3.量词 4.重要搭配 ①  .*? ②  .*?x  ...

  9. topcoder srm 400 div1

    problem1 link 枚举指数,然后判断是不是素数即可. problem2 link 令$f[len][a][b][r]$(r=0或者1)表示子串$init[a,a+len-1]$匹配$goal ...

  10. topcoder srm 699 div1 -3

    1.两个长度为$n$的数组$a,b$,$0 \leq a_{i} <2^{30}$.$b_{i}=-1$或者$b_{i}$为除$a_{i}$外其他数字的抑或值.现在给定$b$,如果不存在$a$, ...