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

xiaoxiao2021-02-28  103

一、自定义注解

一、自定义注解的配置

如果是用的配置文件需要在配置文件中添加配置:

<aop:aspectj-autoproxy/>

如果是使用类进行初始化加载需要在类的上面添加注解

@EnableAspectJAutoProxy

二、自定义注解的约束

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency>

三、自定义注解的模板

/** * 自定义日志注解 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited /** * operationType 操作类型 * dataType 数据类型 */ public @interface MonitorLog { String operationType() default ""; String dataType() default ""; }

1、@Target的用法

java.lang.annotation.Target

用于设定注解使用范围

java.lang.annotation.ElementType

Target通过ElementType来指定注解可使用范围的枚举集合

ElementType的用法

取值注解使用范围METHOD可用于方法上TYPE可用于类或者接口上ANNOTATION_TYPE可用于注解类型上(被@interface修饰的类型)CONSTRUCTOR可用于构造方法上FIELD可用于域上LOCAL_VARIABLE可用于局部变量上PACKAGE用于记录java文件的package信息PARAMETER可用于参数上

这里重点说明下:ElementType. PACKAGE。它并不是使用在一般的类中,而是用在固定的文件package-info.java中。这里需要强调命名一定是“package-info”。由于package-info.java并不是一个合法的类,使用eclipse创建类的方式会提示不合法,所以需要以创建文件的方式来创建package-info.java。

例如,定义可使用范围PACKAGE:

? 1 2 3 4 5 6 7 @Target ({ElementType.PACKAGE,ElementType.METHOD}) @Retention (RetentionPolicy.RUNTIME) @Inherited @Documented public @interface AsynLog {    }

那么,创建文件:package-info.java,内容如下:

复制代码代码如下: @AsynLog package org.my.commons.logs.annotation; 

2、Retention注解

Retention(保留)注解说明,这种类型的注解会被保留到那个阶段. 有三个值:1.RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽略2.RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略3.RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用.

3、Documented 注解

Documented 注解表明这个注解应该被 javadoc工具记录. 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中. 示例6进一步演示了使用 @Documented:

二、切点为注解方式的AOP

一、设置切点为注解

/** * 切点位置 */ @Pointcut(value = "@annotation(com.xx.xx.log.MonitorLog)") public void pointMethod() { }

二、获取切点注解中的参数

@AfterReturning(value = "@annotation(ml)",argNames="ml") public void afterMethodNormally(MonitorLog ml) { String operationType = ml.operationType(); String dataType = ml.dataType(); }

三、获取切点方法中的参数

@After(value = "pointMethod()") public void afterMethod(JoinPoint joinPoint) { //获取方法名 String methodname = joinPoint.getSignature().getName(); //获取类名 String classname = joinPoint.getTarget().getClass().getName(); System.out.println("执行类名:"+classname+" 执行方法: "+methodName); }

四、AOP注解

* @Before 在方法执行前 * @AfterReturning 在方法正常执行之后 * @AfterThrowing 在方法发生异常时执行的方法 * @After 在方法执行之后执行,无论是否发生异常

五、基于JoinPoint获取方法上的注解

/** * 当方法正常执行结束后将当前的方法中的信息进行存储 */ @AfterReturning(value = "pointMethod()") public void afterMethodNormally(JoinPoint joinPoint) { //获取操作时间 String time = getCurrentTime(); try{ //初始化封装对象 DownloadRecord dr = new DownloadRecord(); //封装时间信息 dr.setDownloadTime(new Date()); //获取session中用户信息 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); SecurityContextImpl securityContextImpl = (SecurityContextImpl) request.getSession().getAttribute("SPRING_SECURITY_CONTEXT"); User user = (User)securityContextImpl.getAuthentication().getPrincipal(); //封装用户信息 dr.setDownloadUserId(user.getNickName()); dr.setDownloadUserName(user.getUsername()); //获取下载类型 //获取当前方法 Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature)signature; Method targetMethod = methodSignature.getMethod(); //获取方法上的注解 DownloadAnnotation da = targetMethod.getAnnotation(DownloadAnnotation.class); String downloadType = da.downloadType(); //封装下载类型 dr.setDownloadType(downloadType); //获取录音uuid Object[] args = joinPoint.getArgs(); //封装录音信息 if(args != null && args.length > 0) { dr.setVoiceName(String.valueOf(args[0])); dr.setVoiceNumber(String.valueOf(args[0])); } logger.info("下载时间为:"+time+" 下载用户为:"+user.getUsername() +" 下载类型为:"+downloadType+" 下载标识为:"+args[0]); //保存下载信息 downloadRecordDao.save(dr); } catch (Exception e) { e.printStackTrace(); logger.error("获取下载记录时的执行AfterReturning发生异常,时间为:"+time); //为了事务回滚 抛出运行时异常 throw new RuntimeException("获取下载记录时发生异常"); } }

六、获取返回值

@AfterReturning(value = "pointcut() && @annotation(operateLog)", returning = "result") public Object afterReturning(JoinPoint jionPoint, OperateLog operateLog, Object result){ System.out.println(jionPoint.getArgs()); String methodName = jionPoint.getSignature().getName(); System.out.println(methodName); System.out.println(operateLog.operateType()); return result; }

转载请注明原文地址: https://www.6miu.com/read-27378.html

最新回复(0)