2019独角兽企业重金招聘Python工程师标准>>>
首先感谢大家写的有关AOP的博客,本人参考了很多篇博客,走了一点小弯路,所以在此记录下配置的过程。 1、Mavan的相关依赖
2、Spring 的配置文件
3、Struts2 的配置文件
4、日志实体(省略数据库的操作)
package com.gxuwz.entity;import javax.persistence.*;
@Entity
@Table(name = "sys_log")
public class SysLog extends BaseEntity{private static final long serialVersionUID = -2894437117210657269L;@Column(name = "log_ip_add")private String ipAdd; // IP地址@Column(name = "log_msg")private String msg; // 消息@Column(name = "log_method")private String method; // 方法@Column(name = "log_clazz")private String clazz; // 类名@Column(name = "log_username")private String username; // 用户名@Column(name = "log_create_date")private String createDate; //创建时间// 省略get、set的方法
}
5、自定义AOP的注解
package com.gxuwz.annotation;import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME) //注解会在class中存在,运行时可通过反射获取
@Target(ElementType.METHOD) //目标是方法
@Documented //文档生成时,该注解将被包含在javadoc中,可去掉
public @interface LogMsg
{String msg() default "";}
6、切面
package com.gxuwz.annotation;import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;import com.gxuwz.entity.SysLog;
import com.gxuwz.entity.SysUser;
import com.gxuwz.service.ILogService;
import com.gxuwz.util.DateUtils;
import com.opensymphony.xwork2.ActionContext;import java.lang.reflect.Method;
import java.util.Map;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;@Aspect
@Component
public class LogAspect {private static final Logger logger = Logger.getLogger(LogAspect.class);private SysLog log = new SysLog(); // 定义一个日志对象@Resource(name = "logService")private ILogService logService;/*** 定义Pointcut,Pointcut的名称,此方法不能有返回值,该方法只是一个标示*/@Pointcut("@annotation(com.gxuwz.annotation.LogMsg)")public void controllerAspect() {System.out.println("我是一个切入点");}/*** 前置通知(Before advice) :在某连接点(JoinPoint)之前执行的通知,但这个通知不能阻止连接点前的执行。* * @param joinPoint*/@Before("controllerAspect()")public void doBefore(JoinPoint joinPoint) {System.out.println("=====LogAspect前置通知开始=====");// handleLog(joinPoint, null);}/*** 后通知(After advice) :当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。* * @param joinPoint*/@AfterReturning(pointcut = "controllerAspect()")public void doAfter(JoinPoint joinPoint) {System.out.println("=====LogAspect后置通知开始=====");handleLog(joinPoint, null); // 等执行完SQL语句之后再记录,避免获取不到Session}/*** 抛出异常后通知(After throwing advice) : 在方法抛出异常退出时执行的通知。* * @param joinPoint* @param e*/@AfterThrowing(value = "controllerAspect()", throwing = "e")public void doAfter(JoinPoint joinPoint, Exception e) {System.out.println("=====LogAspect异常通知开始=====");// handleLog(joinPoint, e);}/*** 环绕通知(Around advice)* :包围一个连接点的通知,类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为* ,也可以选择不执行。* * @param joinPoint*/@Around("controllerAspect()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("=====LogAspect 环绕通知开始=====");//handleLog(joinPoint, null);Object obj = joinPoint.proceed();System.out.println("=====LogAspect 环绕通知结束=====");return obj;}/*** 日志处理* * @param joinPoint* @param e*/private void handleLog(JoinPoint joinPoint, Exception e) {try {HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);System.out.println("IP地址:" + request.getRemoteAddr());log.setIpAdd(request.getRemoteAddr());Map
7、在Controller的方法上写注解、例如
/*** 用户控制器* @author 小胡 * @date 2017年5月28日*/
public class UserController extends AbstractBaseController{@LogMsg(msg = "用户登陆")public String doLogin(){...}
}