spring-Aop应用日志处理

       上文讲解了sping Aop的基础概念与实现逻辑,本文从实践出发介绍sping进行aop配置并实现日志打印过程。


       环境介绍:spring4.0 release版本,前端使用spring mvc框架。


       1. 定义注解拦截器

/**
 * 自定义注解 拦截service
 */
@Component
public class LogInterceptor {
	@Resource
	private SystemLogService systemLogService;
	private final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);

	/**
	 * @Description: 前置通知
	 * @param @param joinPoint
	 * @return void
	 * @author whp
	 */
	public void before(JoinPoint joinPoint) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		HttpSession session = request.getSession();
		
		String methodName = joinPoint.getSignature().getName();
		try {
			logger.info("=====Entering   " + methodName + "()=====");
			logger.info("请求方法:"
					+ (joinPoint.getTarget().getClass().getName() + "."
							+ joinPoint.getSignature().getName() + "()"));
		} catch (Exception e) {
			// 记录本地异常日志
			logger.error("==Entering   " + methodName + "()异常==");
			logger.error("异常信息:{}", e.getMessage());
		}

	}

	/**
	 * @Description: 后置通知
	 * @param @param joinPoint
	 * @return void
	 * @author whp
	 */
	public void after(JoinPoint joinPoint) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		HttpSession session = request.getSession();
		// 请求的IP
		String methodName = joinPoint.getSignature().getName();
		try {
			logger.info("=====leaving   " + methodName + "()=====");
			// contentToTxt("=====leaving   " + methodName + "()=====");
		} catch (Exception e) {
			// 记录本地异常日志
			logger.error("==leaving   " + methodName + "()异常==");
			logger.error("异常信息:{}", e.getMessage());
		}
	}

	/**
	 * @Description: 通用异常通知
	 * @param @param joinPoint
	 * @param @param e
	 * @param @throws NoSuchFieldException
	 * @param @throws SecurityException
	 * @return void
	 * @author whp
	 */
	public void afterThrowing(JoinPoint joinPoint, Throwable e)
			throws NoSuchFieldException, SecurityException {

		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		HttpSession session = request.getSession();
		// 请求的IP
		String params = "";
		Object[] args = joinPoint.getArgs();
		if (args != null && args.length > 0) {
			for (Object obj : args) {
				if (null != obj) {
					Field[] fields = obj.getClass().getDeclaredFields();
					if (null != fields && fields.length > 0) {
						params += obj.getClass().getSimpleName() + "[";
						for (Field field : fields) {
							String name = field.getName();
							Object value = getFieldValueByName(name, obj);
							if (null != value && (!"".equals(value))) {
								params += name + ":" + value + ";";
							}
						}
						params += "],";
					} else {
						params += obj.getClass().getSimpleName() + ":"
								+ obj.toString() + ";";
					}
				}
			}

		}
		String methodName = joinPoint.getSignature().getName();
		try {
			/* ========控制台输出========= */
			logger.info("=====Entering   " + methodName + "()异常=====");
			logger.info("异常代码:" + e.getClass().getName());
			logger.info("异常信息:" + e.getMessage());
			logger.info("异常方法:"
					+ (joinPoint.getTarget().getClass().getName() + "."
							+ joinPoint.getSignature().getName() + "()"));
			logger.info("请求参数:" + params);
			// ==========数据库日志=========
			logger.info("=====leaving   " + methodName + "()异常=====");
		} catch (Exception ex) {
			// 记录本地异常日志
			logger.error("==" + methodName + "()异常通知异常==");
			logger.error("异常信息:{}", ex.getMessage());
			logger.error("==" + methodName + "()异常结束==");
		}
		// ==========记录本地异常日志==========
		logger.error("异常方法:{}异常代码:{}异常信息:{}参数:{}", joinPoint.getTarget()
				.getClass().getName()
				+ joinPoint.getSignature().getName(), e.getClass().getName(),
				e.getMessage(), params);

	}

	/**
	 * @Description: 根据属性名获取属性值
	 * @param @param fieldName
	 * @param @param o
	 * @param @return
	 * @return Object
	 * @author whp
	 */
	private Object getFieldValueByName(String fieldName, Object o) {
		try {
			String firstLetter = fieldName.substring(0, 1).toUpperCase();
			String getter = "get" + firstLetter + fieldName.substring(1);
			if (o.getClass().getName().startsWith("com.cxg")) {
				Method method = o.getClass().getMethod(getter, new Class[] {});
				Object value = method.invoke(o, new Object[] {});
				return value;
			} else {
				return null;
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			return null;
		}
	}


}

        2. 将拦截器注入到springmvc.xml中


<bean id="logInterceptor" class="com.cxg.interactiveweb.logs.util.LogInterceptor" />

       3. 配置aop容器

	<aop:config proxy-target-class="true">
		<aop:aspect id="logAspect" ref="logInterceptor">
			<aop:pointcut
				expression="execution(* com.cxg.interactiveweb.*.controller..*.*(..))"
				id="logControllerCut" />
			<aop:pointcut
				expression="execution(* com.cxg.interactiveweb.*.service..*.*(..))"
				id="logServiceCut" />
			<!-- <aop:around method="around" pointcut-ref="logPointCut" /> -->
			<aop:before method="before" pointcut-ref="logControllerCut" />
			<aop:after method="after" pointcut-ref="logControllerCut" />
			<aop:after-throwing method="afterThrowing"
				pointcut-ref="logControllerCut" throwing="e" />
			<aop:before method="before" pointcut-ref="logServiceCut" />
			<aop:after method="after" pointcut-ref="logServiceCut" />
		</aop:aspect>
     </aop:config>

        上面创建过程非常简单,首先定义一个拦截器类,该类实现了,before,after,afterThrowing三个方法,添加@Component注解,将拦截器注入到spring容器。


        配置AOP,定义aspect切面,定义pointcut切入点,使用expression将所有的controller和service方法定义切入点,通过before,after,after-throwing定义advice,指定切入方法。



你可能感兴趣的:(spring-Aop应用日志处理)