利用切面 基于注解和配置对spring进行异常和日志处理

首先在maven项目中添加spring 切面的包在pom文件中添加pom依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.3.12.RELEASE</version>
</dependency>
然后再spring-mvc配置文件中的xsi:schemaLocation新增

http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
将自己的切面类注入spring容器

   <bean id="systemLogAspect" class="com.demo.annotation.SystemLogAspect"/> 
新增开启注解的配置和 CGLIB代理

<mvc:annotation-driven />
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
然后定义自己的切面类

@Aspect
@Component
public class SystemLogAspect {
	// Controller层切点
	@Pointcut("@annotation(com.demo.annotation.SystemControllerLog)")
	public void controllerAspect() {
	}
	
	@Pointcut("execution(* com.demo.controller..*.*(..))")
	public void exceptionAspect() {	
	}

@After("controllerAspect()")
	public void doAfter(JoinPoint joinPoint) {
		Object[] methodParams = joinPoint.getArgs(); 
		HttpServletRequest request = ((ServletRequestAttributes)     RequestContextHolder.getRequestAttributes()).getRequest();
		HttpSession session = request.getSession();
		// 读取session中的用户
		Users user = (Users) session.getAttribute("user");
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
		    String time = sdf.format(new Date());
			InetAddress addr = InetAddress.getLocalHost();
			//获得本机IP
			String ip=addr.getHostAddress();
			ArrayList result=getControllerMethodDescription(joinPoint);
			int operateType=(int) result.get(1);
			String description=(String) result.get(0);
			int state=logService.insertLog(user.getDepartmentId(), operateType, user.getUserName(), user.getRealName(), description);
			System.out.println("=====后置通知结束=====");
		} catch (Exception e) {
			// 记录本地异常日志
			logger.error("==后置通知异常==");
			logger.error("异常信息:{}", e.getMessage());
		}
	}
@AfterThrowing(pointcut = "exceptionAspect()", throwing = "e")
	public void doAfterThrowing(JoinPoint joinPoint,Throwable e) throws UnknownHostException {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		HttpSession session = request.getSession();
		Users user = (Users) session.getAttribute("user");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
	    String time = sdf.format(new Date());
		InetAddress addr = InetAddress.getLocalHost();
		String ip=addr.getHostAddress();
		String params = "";
		if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) {
			for (int i = 0; i < joinPoint.getArgs().length; i++) {
				params += JSON.toJSONString(joinPoint.getArgs()[i]) + ";";
			}
		}
		try {
			System.out.println("=====异常通知开始=====");
			System.out.println("异常代码:" + e.getClass().getName());
			System.out.println("异常信息:" + e.getMessage());
			System.out.println("异常方法:"+ (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
			System.out.println("请求人:" + user.getRealName());
			System.out.println("请求IP:" + ip);
			System.out.println("请求参数:" + params);
			// 保存数据库
			System.out.println("=====异常通知结束=====");
			SystemException systemException=new SystemException();
			systemException.setExceptionCode(e.getClass().getName());
			systemException.setExceptionFunction((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
			systemException.setExceptionMessage(e.getMessage());
			systemException.setIp(ip);
			systemException.setUserId(user.getId());
			systemException.setUserRealName(user.getRealName());
			systemException.setParams(params);
			logService.insertSysException(systemException);
		} catch (Exception ex) {
			// 记录本地异常日志
			logger.error("==异常通知异常==");
			logger.error("异常信息:{}", ex.getMessage());
		}
	}
/**
	 * 获取注解中对方法的描述信息 用于Controller层注解
		 * @param joinPoint  切点
	 * @return 方法描述
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static ArrayList getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		Class targetClass = Class.forName(targetName);
		Method[] methods = targetClass.getMethods();
		ArrayList result=new ArrayList<>();
		String description = "";
		int operatorType=0;
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				Class[] clazzs = method.getParameterTypes();
				if (clazzs.length == arguments.length) {
					Annotation aaa=method.getAnnotation(SystemControllerLog.class);
					description = method.getAnnotation(SystemControllerLog.class).description();
					operatorType= method.getAnnotation(SystemControllerLog.class).operateType();
					result.add(description);
					result.add(operatorType);
					break;
				}
			}
		}
		return result;
	}
}
其中controllerAspect为基于注解方式的切面拦截 exceptionAspect() 为基于包的切面拦截 @After为后置通知,也就是说在方法执行完成之后才进行切面拦截,@AfterThrowing为抛出异常之后进行切面拦截,下面是对一些注解的详细描述

getControllerMethodDescription 方法是根据切点获取方法上面注解的参数

自定义SystemControllerLog注解

/**
 * 自定义注解 拦截Controller
 */
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
	/** 要执行的具体操作比如:用户登录 **/  
	public String description() ;
	
	public int operateType();
}
然后是使用 SystemControllerLog注解

	/**
	 * 
	 * @param session
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/inApproveBrief", method = RequestMethod.POST)
	@SystemControllerLog(description = operat.S_INNER_BORROW_PROCESS, operateType =operat.INNER_BORROW_PROCESS)
	public void inApproveBrief(HttpSession session, HttpServletRequest request, HttpServletResponse response)
			throws IOException {	
	}









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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值