引言
众所周知,spring aop是基于动态代理模式的,而动态代理又根据是否实现接口分为两类:1.基于JDK的动态代理和基于cglib的动态代理,下面就两者的区别做些简单概括(如所示):https://github.com/TomasXiong/design-pattern.git
本文基于spring boot实现一个简单的用户日志拦截记录,记录用户的操作模块和操作时间。
首先,第一步,建议日志记录表:
CREATE TABLE log_record
(
id
int(11) NOT NULL AUTO_INCREMENT COMMENT ‘ID’,
request_method
varchar(255) DEFAULT NULL,
request_time
varchar(255) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
第二步:引入aop依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
第三步:开始编码
/**
- 日志注解
- @author 64507
*/
@Target(ElementType.METHOD) //方法注解(元注解)
@Retention(RetentionPolicy.RUNTIME) //运行时(元注解)
@Documented
public @interface LogAnnotation {
String logRecord(); //注解只有成员变量,没有方法,方法名即为成员变量的名字,返回值类型即为该成员变量的类型,成员变量的类型必须是8种基本数据类型和类,接口,数组以及注解
}
建立实体bean:LogRecord
切面类
@Aspect
@Component
public class LogAspect {
private long currentTime = 0L;
@Autowired
LogService logService;
//配置切入点
@Pointcut("@annotation(com.kfit.spring_boot_mybatis.annotation.LogAnnotation)")
public void pointCut() {
}
/**
* 环绕通知
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("pointCut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = null;
currentTime = System.currentTimeMillis();
result = joinPoint.proceed();
long wasteTime = System.currentTimeMillis() - currentTime;
LogRecord log = new LogRecord("INFO",String.valueOf(wasteTime));
MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
Method method = methodSignature.getMethod();
LogAnnotation logAnnotation = method.getAnnotation(com.kfit.spring_boot_mybatis.annotation.LogAnnotation.class);
//String record = logAnnotation.logRecord(); //切面记录
String methodName = joinPoint.getTarget().getClass().getName()+"."+methodSignature.getName()+"()";
Object[] objectArr = joinPoint.getArgs();
log.setRequestMethod(methodName);
String requesTtime = DateUtil.getCurrentDate();
log.setRequestTime(requesTtime);
logService.addRecord(log);
System.out.println("===methodName="+methodName+" objectArr=="+objectArr);
//核心方法,从joinPoint获取参数值
//logService.save(getUsername(), StringUtils.getIP(RequestHolder.getHttpServletRequest()),joinPoint, log);
return result;
}
}
标签类
/**
- 日志注解
- @author 64507
*/
@Target(ElementType.METHOD) //方法注解(元注解)
@Retention(RetentionPolicy.RUNTIME) //运行时(元注解)
@Documented
public @interface LogAnnotation {
String logRecord(); //注解只有成员变量,没有方法,方法名即为成员变量的名字,返回值类型即为该成员变量的类型,成员变量的类型必须是8种基本数据类型和类,接口,数组以及注解
}
service类
@Service
public class LogService {
@Autowired
private LogRecordMapper logRecordMapper;
public int addRecord(LogRecord record) {
return logRecordMapper.insert(record);
}
}
controller层调用
@LogAnnotation(logRecord=“操作记录”)
@RequestMapping("/save")
public int save(){
for(int i =0;i<10;i++) {
Demo demo = new Demo();
demo.setDemoName(“tt”+i);
demo.setDemoCode(“00”+i);
demoService.save(demo);
}
return 1;
}
结果: