AOP+日志打印
例:我这个是捕捉error异常的打印
注释:Proceedingjoinpoint 继承了 JoinPoint 。是在JoinPoint的基础上暴露出 proceed 这个方法。proceed很重要,这个是aop代理链执行的方法。Proceedingjoinpoint 就能支持 aop:around 这种切面(而其他的几种切面只需要用到JoinPoint,这跟切面类型有关)
注释:用到哪个切入点就写哪个 不需要全都写;
equalsIgnoreCase:比较不区分大小写
equals:比较区分大小写
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Aspect
@Component
public class aopMonitor(){
//参数作用(使用指定类初始化日志对象,在日志输出的时候,可以打印出日志信息所在类)
//如:Logger logger = LoggerFactory.getLogger(com.Book.class);
//logger.debug("日志信息");
//将会打印出: com.Book : 日志信息
//Logger.getLogger(); 这个是apache里的log4j包下的Logger,因为在你配置log4j的properties的属性文件时里面的属性都是用的apache的所以这两个要对应的都是apach的
private static final Logger logger = Logger.getLogger(JavaMonitor.class.getName());
//CONTROLLER_POINT要写到切点注解的参数中
//execution(): 表达式主体。
//第一个*号:表示返回类型,*号表示所有的类型。
//包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
//第二个*号:表示类名,*号表示所有的类。
//*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
public static final String CONTROLLER_POINT = "execution(* com.drefore.heatingsystem.admin.controller..*.*(..))"
//这个方法是用来计算时间的
private void printTime(String methodName, long startTime, long endTime){
long diffTime = endTime - startTime;
if(diffTime > 0){
logger.info("=====>>" + methodName + "方法消耗时间:" + diffTime + "ms");
}
}
//@Pointcut注解来定义切点,把切点和通知两者解开
@Pointcut(CONTROLLER_POINT)
private void controllerPointcutMethid(){
}
//声明前置通知
@Before("controllerPointcutMethid()")
public void controllerDoBefore(JoinPoint joinPoint){
}
//声明后置通知
@AfterReturning(pointcut = "controllerPointcutMethid()", returning = "object")
public void controllerDoAfterReturning(JoinPoint joinPoint,Object object){
}
//声明例外通知
@AfterThrowing(pointcut = "controllerPointcutMethid()", throwing = "e")
public void controllerDoAfterThrowing(Exception e){
}
//声明最终通知
@After("controllerPointcutMethod()")
public void controllerDoAfter(){
}
//声明环绕通知
@Around("controllerPointcutMethod()")
public Object controllerDoAround(ProceedingJoinPoint joinPoint){
//定义返回对象,得到方法需要的参数
Object result = null;
//获取访问目标方法的参数
Object[] args = joinPoint.getArgs();
//获取当前时间
long startTime = System.currentTimeMillis();
//拦截Controller的名字
String controllerName = joinPoint.getTarget().getClass().getSimpleName();
//拦截方法名称
String methodName = joinPoint.getSignature.getName();
String resultType = ((MethodSignature)proceedingJoinPoint.getSignature()).getReturnType().getSimpleName().toString();
HttpServletResponse response = null;
Model model = null;
for(Object param : args){
//instanceof是java的双目运算符,用来判断一个对象是否为一个类的实例
if(param instanceof HttpServletResponse){
response = (HttpServletRsponse) param;
}
if(param instanceof Model){
model = (Model) param;
}
}
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
try{
result = proceedingJoinPoint.proceed(args);//运行目标函数时如果目标函数有参数需要传递进去,args就是那个参数数组
} catch(Throwable throwable){
logger.error("==========>>执行异常<<==========");
//获取报错类的在项目中的具体路径
logger.error("URL : " + request.getRequestURL().toString());
//获取报错类的请求方式
logger.error("HTTP_METHOD : " + request.getMethod());
//获取访问的IP地址
logger.error("IP : " + request.getRemoteAddr());
logger.error("CLASS_METHOD : " + proceedingJoinPoint.getSignature().getDeclaringTypeName() + "." + proceedingJoinPoint.getSignature());
//获取传递到方法中的参数
logger.error("ARGS : " + Arrays.toString(proceedingJoinPoint.getArgs()));
//异常信息出错类型(例如空指针异常....等等)
logger.error("异常信息:[" + throwable.toString() + "]");
for(int i=0; i<throwable.getStackTrace().length; i++){
logger.error("轨迹" + i + ":[" + throwable.getStackTrace()[i].toString() + "]");
}
result = systemExceptionCheck(controllerName,methodName,resultType,request,response,model);
}
long endTime = System.currentTimeMillis();
this.printTime("控制器访问时间",startTime,endTime);
return result;
}
private Object systemExceptionCheck(String controllerName, String methodName, String returnType, HttpServletRequest request, HttpServletResponse response,Model model){
if(request.getHeader("x-requested-with") != null && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
if(returnType.equals("Map")){
Map<String, Object> result = nwe HashMap<>();
result.put("result","error");
result.put("errorCode","服务器状态异常");
return result;
}else if(returnType.equalsIgnoreCase("String")){
return "/co,,om/error/iframe_default";
}else{
return "/common/error/default";
}
}
return null;
}
}