自定义注解实现Aop编程
使用的场合:需要把操作日志和系统错误日志放到mongodb中
1.自定义注解类
package com.lenovo.pcsd.bp.businesspartner.filter; import java.lang.annotation.*; /** * *自定义注解定义 * @author * @version V1.0 */ @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface LoggerArchive { /** 要调用的具体接口 **/ String value() default ""; }
注解用于的地方
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.METHOD) //方法
@LoggerArchive //注解只能用在方法参数和方法上
public PageUtil<Map<String, String>> getCommitMentNumberList(@RequestParam("pagenum")String pagenum, @RequestParam("pagesize")int pagesize){
int pagenum1=Integer.parseInt(pagenum);
PageUtil<Map<String, String>> pageUtil = CountLimitService.getNumberList(pagenum1, pagesize);
return pageUtil;
}
2. 切面类的编写
package com.lenovo.pcsd.bp.businesspartner.filter;
import com.lenovo.pcsd.bp.businesspartner.utils.PageUtil;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* @author <a href="mailto:hongyu.liu@logosdata.com"> liuhongyu </a><br>
* @version V1.0
*/
@Aspect
@Component
public class LoggerInterceptor {
protected Logger log = (Logger) Logger.getLogger(this.getClass());
/**
* 定义切点
*/
@Pointcut("@annotation(com.filter.LoggerArchive)")
public void logPointCut() {
}
/**
* 环绕通知 记录服务调用次数 以及记录接口日志
*/
/*@Around(value = "logPointCut()")*/ //第一种 在方法的上方
@Around("execution(* com.controller.*.*(..))") //第二种不需要自定义注解 利用表达式去执行controller层下所有的类
public object aroundMod(ProceedingJoinPoint proceedingJoinPoint)
throws Throwable {
object result = null;
// 操作描述
String targetName = proceedingJoinPoint.getTarget().getClass()
.getName();
String methodName = proceedingJoinPoint.getSignature().getName();
Object[] arguments = proceedingJoinPoint.getArgs();
Class<?> targetClass =Class.forName(targetName);
try {
// 执行目标方法
result = proceedingJoinPoint.proceed();
//记录正确的日志
System.out.println("正确的日志");
System.err.println(targetClass);
System.err.println(methodName);
} catch (Exception e) {
//记录错误的日志
System.out.println("错误的日志");
System.err.println(targetClass);
System.err.println(methodName);
System.out.println(e.getMessage());
e.printStackTrace();
} finally {
}
return result;
}
/**
* 异常通知 记录调用接口出现异常错误之后的接口日志
*
* @param joinPoint
* @param ex
* @throws Exception
*/
@AfterThrowing(value = "logPointCut()", throwing = "ex")
public void afterThrowing(JoinPoint joinPoint, Exception ex)
throws Exception {
}
}
注意:aroundMod方法的返回值为object(不能为其他值),与controller的放回值 得匹配,不然会出现转换异常。
service层代码
@Override
public void updateCountLimit(CountLimit CountLimit) {
try {
bpCountLimitMapper.updateCountLimit(CountLimit);
}catch (RuntimeException e){
throw new AppcationException(ExceptionEnum.NOTFOUNTVALUE);
}
}
在service层抛出异常,统一在controller层捕捉不理, 通过aop切面实现错误日志的输出
调试结果
错误信息,正确信息在规定的地方编写代码可以打印到控制台。