环境:dubbo 下的ssm框架
1.AOP切面代码(web层)
@Aspect @Component public class LogAopController { @Autowired private HttpServletRequest request; //需要在web.xml配置 @Reference //注意不同的项目下不能使用@Autowired 要是用@Reference private ISysLogService service; private Date visitTime;//5开始时间 private Class clazz;//6访问的类 private Method method;//7访问的方法 /* 1如何获取操作者? * 2如何获取访问的ip * 3如何获取访问的url * 4如何获取执行的时长 */ //前置通知,主要获取开始时间,执行的类是哪一个,执行了哪个方法 @Before("execution(* com.qingcheng.controller.goods.SpuController.*(..))")//.*是包下的所有类 .*是类下的所有方法 public void doBefore(JoinPoint jp) throws NoSuchMethodException { visitTime=new Date();//当前时间就是开始的时间 clazz=jp.getTarget().getClass();//获取类 String methodName=jp.getSignature().getName();//只能获取方法的名字 Object[] args = jp.getArgs();//获取访问的方法参数 //获取具体的方法对象 if (args == null||args.length == 0){ //无参数 method=clazz.getMethod(methodName); //根据方法的名字,只能获取无参数的方法 }else { //有参数 Class[] classArgs=new Class[args.length]; for (int i=0;i<args.length;i++){ classArgs[i]=args[i].getClass();//把方法的每个参数都存入到数组中 } method=clazz.getMethod(methodName,classArgs); } } //后置通知 @After("execution(* com.qingcheng.controller.goods.SpuController.*(..))") public void doAfter(JoinPoint jp){ //4如何获取执行的时长? String time= String.valueOf(new Date().getTime()-visitTime.getTime()); //3如何获取访问的url String url=""; if(clazz!=null&&method!=null&&clazz!= LogAopController.class){ //获取url @RequestMapping("/findAll.do") //子类 对象名= (子类) 父类; 强制转换 将父类对象赋予子类对象需要强制转换为子类对象(小知识点!!!!) RequestMapping classAnnotation = (RequestMapping) clazz.getAnnotation(RequestMapping.class); if(classAnnotation!=null){ //1.获取类上的路径 String[] classValue=classAnnotation.value(); //2.获取方法上的路径 RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class); if (methodAnnotation!=null){ String[] methodValue = methodAnnotation.value();//获取了方法上的路径 //类路径+方法路径 url=classValue[0]+methodValue[0]; } } } //如何获取2如何获取访问的ip //1.配置web.xml 获取HttpServletRequest 2.注入依赖获取request对象 String ip = request.getRemoteAddr(); ///获取ip //封装信息 Syslog syslog=new Syslog(); UUID uuid = UUID.randomUUID(); syslog.setId(uuid.toString());//1 syslog.setExecutionTime(time);//2 syslog.setIp(ip);//3 syslog.setMethod("[类]"+clazz.getName()+"[方法]"+method.getName());//4 syslog.setUrl(url);//5 syslog.setUsername("TEST");//6 syslog.setVisitTime(visitTime);//7 System.out.println(syslog); service.saveLog(syslog); } }View Code
2.配置mvc的xml文件
<context:component-scan base-package="扫描包路径"/>
<aop:aspectj-autoproxy proxy-target-class="true"/> <!-- 支持AOP的注解支持,AOP底层使用代理技术-->
3.web层的查询日志代码
@RestController @RequestMapping("/spuLog") public class LogSpuController { @Reference private ISysLogService spuService; @GetMapping("findAll") public List<Syslog> findAll(){ return spuService.findAll(); } }View Code
4.pojo
@Table(name = "tb_syslog") public class Syslog implements Serializable { @Id private String id; private Date visitTime; private String visitTimestr; //注意 visitTimestr 设计数据库字段为visit_timestr Mapper才会识别 private String username; private String ip; private String url; private String executionTime; private String method; }View Code
5.service接口
public interface ISysLogService { public void saveLog(Syslog syslog); //保存日志 List<Syslog> findAll();//查询所有日志 }
6.service层下的dao (使用的通用mapper)
public interface ISysLogMapper extends Mapper<Syslog> { }
7.service层下的接口实现
@Service public class ISysLogServiceImpl implements ISysLogService { @Autowired private ISysLogMapper iSysLogMapper; public void saveLog(Syslog syslog) {//保存日志 iSysLogMapper.insert(syslog);//当mysql数据库设置默认值时,如果使用insert插入会把字段为空的值也插入到数据库,所以数据库设置的默认值也没用 } public List<Syslog> findAll() { return iSysLogMapper.selectAll(); } }
切面配置好后会显示m->
8.测试