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

一、自定义注解

一、自定义注解的配置

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

<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;
	}






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值