1、
Java代码
- <aspectj.version>1.7.4.RELEASE</aspectj.version>
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjweaver</artifactId>
- <version>${aspectj.version}</version>
- </dependency>
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjrt</artifactId>
- <version>${aspectj.version}</version>
- </dependency>
注意:如果JDK1.7的 必须这里也是1.7+
2、
Java代码
- <aop:config proxy-target-class="true"></aop:config>
- <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
- <property name="securityManager" ref="securityManager"/>
- </bean>
- <aop:aspectj-autoproxy proxy-target-class="true"/>
注意:下载 必须在spring-mvc.xml里面,且有两个aop配置,下面那个是必须的,上面那个可能不是必须的(上面那个应该是spring aop的,如果有aspectJ了,可以不需要)
3、AOP类
Java代码
- package com.kingen.aop;
- import java.lang.reflect.Method;
- import javax.servlet.http.HttpServletRequest;
- import javax.transaction.Transactional;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.annotation.AfterReturning;
- import org.aspectj.lang.annotation.AfterThrowing;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Pointcut;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.stereotype.Component;
- import org.springframework.util.Assert;
- import org.springframework.web.context.request.RequestContextHolder;
- import org.springframework.web.context.request.ServletRequestAttributes;
- import com.kingen.bean.Log;
- import com.kingen.bean.User;
- import com.kingen.service.log.LogService;
- import com.kingen.util.Constants;
- import com.kingen.util.DateUtils;
- import com.kingen.util.SpringContextHolder;
- import com.kingen.util.StringUtils;
- import com.kingen.util.UserUtils;
- /**
- * 日志AOP
- *
- * @author wj
- * @date 2016-11-16
- *
- */
- @Aspect
- @Component
- public class LogAOP {
- private static LogService logService = SpringContextHolder.getBean(LogService.class);
- 下载
- // 本地异常日志记录对象
- private Logger logger = LoggerFactory.getLogger(getClass());
- /**
- * 在所有标注@LogAnnotation的地方切入
- *
- * @param joinPoint
- */
- @Pointcut("@annotation(com.kingen.aop.LogAnnotation)")
- public void logAspect() {
- }
- // @Around(value = "aApplogic() && @annotation(annotation) &&args(object,..)
- // ", argNames = "annotation,object")
- // public Object around(ProceedingJoinPoint pj,
- // LogAnnotation annotation, Object object) throws Throwable {
- // System.out.println("moduleName:"+annotation.moduleName());
- // System.out.println("option:"+annotation.option());
- // pj.proceed();
- // return object;
- // }
- /**
- * 前置通知 用于拦截Controller层记录用户的操作
- *
- * @param joinPoint
- * 切点
- * @throws Exception
- */
- // @Around(value = "logAspect() && @annotation(annotation) &&args(object,..) ", argNames = "annotation,object")
- // public void doAround(ProceedingJoinPoint joinPoint, LogAnnotation annotation, Object object) {
- //用@Around 会导致controller不执行,不返回页面
- // @After(value = "logAspect() && @annotation(annotation) &&args(object,..) ", argNames = "annotation,object")
- // public void doAfter(JoinPoint joinPoint, LogAnnotation annotation, Object object) {
- @AfterReturning(value = "logAspect() && @annotation(annotation) &&args(object,..) ", argNames = "", returning = "retVal")
- public void doAfterReturning(JoinPoint joinPoint, LogAnnotation annotation, Object object, String retVal) {
- HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
- .getRequest();
- try {
- // String title = getAnnotationValue(joinPoint);
- String title = getAnnotationValue(annotation);
- saveLog(request, title);
- } catch (Exception e) {
- e.printStackTrace();
- // 记录本地异常日志
- logger.error("==异常通知异常==");
- logger.error("异常信息:{}", e.getMessage());
- }
- }
- /**
- * 异常通知 用于拦截service层记录异常日志
- *
- * @param joinPoint
- * @param e
- */
- // 方法 catch住异常的话,这里执行不到
- // @AfterThrowing(pointcut = "logAspect()", throwing = "e")
- @AfterThrowing(value = "logAspect() && @annotation(annotation) &&args(..) " , throwing = "e")
- public void doAfterThrowing(JoinPoint joinPoint, LogAnnotation annotation, Exception e) {
- HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
- .getRequest();
- try {
- // String title = getAnnotationValue(joinPoint);
- String title = getAnnotationValue(annotation);
- saveLog(request, title, e);
- } catch (Exception ex) {
- // 记录本地异常日志
- logger.error("==异常通知异常==");
- logger.error("异常信息:{}", ex.getMessage());
- }
- }
- 下载
- public static void saveLog(HttpServletRequest request, String title) {
- saveLog(request, title, null);
- }
- /**
- * 保存日志
- */
- @Transactional
- public static void saveLog(HttpServletRequest request, String title, Exception ex) {
- User user = UserUtils.getCurrentUser();
- if (user != null && user.getUserId() != null) {
- Log log = new Log();
- log.setCreateDate(DateUtils.getDateTime());
- log.setTitle(title);
- log.setType(ex == null ? Log.TYPE_ACCESS : Log.TYPE_EXCEPTION);
- log.setRemoteAddr(StringUtils.getRemoteAddr(request));
- log.setUserAgent(user.getUsername());
- // log.setUserAgent(request.getHeader("user-agent"));
- log.setRequestUri(request.getRequestURI());
- log.setParams(request.getParameterMap());
- // 如果有异常,设置异常信息
- log.setException(ex == null ? null : ex.getMessage());
- // log.setException(ex == null ? null : Exceptions.getStackTraceAsString(ex));
- log.setStatus(ex == null ? Constants.StatusEnum.Success.getIndex() : Constants.StatusEnum.Fail.getIndex());
- // log.setMethod(request.getMethod());
- // 异步保存日志
- // new SaveLogThread(log, handler, ex).start();
- logService.saveLog(log);
- }
- }
- /**
- * 获取注解中对方法的描述信息 用于Controller层注解
- *
- * @param joinPoint
- * 切点
- * @return 方法描述
- * @throws Exception
- */
- @Deprecated
- public static String getAnnotationValue(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();
- String description = "";
- for (Method method : methods) {
- if (method.getName().equals(methodName)) {
- Class[] clazzs = method.getParameterTypes();
- if (clazzs.length == arguments.length) {
- String moduleName = method.getAnnotation(LogAnnotation.class).moduleName();
- String option = method.getAnnotation(LogAnnotation.class).option();
- Assert.hasText(moduleName, "模块名字不应为空");
- Assert.hasText(option, "操作名字不应为空");
- description = moduleName + "-" + option;
- break;
- }
- }
- }
- return description;
- }
- public static String getAnnotationValue(LogAnnotation anno) throws Exception {
- String moduleName = anno.moduleName();
- String option = anno.option();
- Assert.hasText(moduleName, "模块名字不应为空");
- Assert.hasText(option, "操作名字不应为空");
- String description = moduleName + "-" + option;
- return description;
- }
- }
注意这里 @After和 @AfterReturning的区别,总的来说,就是 @After 是无论如何都会执行的,不管有没有异常抛出(这样会导致,在有异常的时候,记录两次日志,after一次、throwing一次);@AfterReturning 在有异常的情况下,不会执行到,因为没有renturn,在retrun之前就throw了。
时间: 2024-10-20 12:08:20