AOP实现Java后台系统日志(超简单详解)

欢迎访问我的个人博客:www.ifueen.com

最近需要做一个Java后台的系统日志功能,由于以前从来没有做过,便去网上查阅资料,尝试着做一下

大体思路:

通过AOP在Controller之前进行切面,新建一个自定义注解,然后在AOP配置里面设置当前操作的模块和功能,然后设置进日志的实体类中,最后保存到数据库中即可完成

首先自定义一个注解:

package com.sure.crm.web.config;

import java.lang.annotation.*;

/**
 * 系统日志的自定义注解
 *
 */
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemLog {
    String module()  default "";
    String methods()  default "";
}

然后在根据自己的情况去配置AOP

在pom.xml中引入依赖

<!--aop的包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>
        <!--切面的一个包(织入)-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.8</version>
        </dependency>

在applicationContext-MVC中配置

<!-- aop配置 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
    <!-- 扫描包支持 -->
    <bean id="aopLogConfig" class="com.sure.crm.web.config.AopLogConfig">
    </bean>

然后写AOP的配置类,在这里对Controller切一下,保存日志

package com.sure.crm.web.config;

import com.sure.crm.domain.Employee;
import com.sure.crm.domain.LogEntity;

import com.sure.crm.service.LogService;
import com.sure.shiro.UserContext;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Aop日志的配置
 *
 */
@Component
@Aspect
public class AopLogConfig {

    //注入service,用来将日志信息保存在数据库
    @Autowired
    private LogService logservice;

    //配置接入点
    @Pointcut("execution(* com.sure.crm.web.controller..*.*(..))")
    private void controllerAspect(){}//定义一个切入点

    @Around("controllerAspect()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {

        //日志实体对象
        LogEntity log = new LogEntity();
        //获取登录用户账户
        HttpServletRequest request = ((ServletRequestAttributes) 				 RequestContextHolder.getRequestAttributes()).getRequest();
        //拿到当前用户,我是通过shiro的主体来取的,各自根据各自情况来进行设置
        Employee user = UserContext.getUser();
        if (null != user){
        	//设置当前用户名
            String name = user.getName();
            log.setUSERID(name);
        }
        //获取系统时间
        String time = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(new Date());
        log.setDATA(time);

        //获取客户端ip
        String ip = request.getRemoteAddr();
        log.setIP(ip);

        //方法通知前获取时间,来计算模块执行时间的
        long start = System.currentTimeMillis();
        // 拦截的实体类,就是当前正在执行的controller
        Object target = pjp.getTarget();
        // 拦截的方法名称,当前正在执行的方法
        String methodName = pjp.getSignature().getName();
        // 拦截的方法参数
        Object[] args = pjp.getArgs();
        // 拦截的放参数类型
        Signature sig = pjp.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Class[] parameterTypes = msig.getMethod().getParameterTypes();

        Object object = null;
        // 获得被拦截的方法
        Method method = null;
        try {
            method = target.getClass().getMethod(methodName, parameterTypes);
        } catch (NoSuchMethodException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (SecurityException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        System.out.println(method);
        if (null != method) {
            // 判断是否包含自定义的注解,说明一下这里的SystemLog就是我自己自定义的注解
            if (method.isAnnotationPresent(SystemLog.class)) {
                SystemLog systemlog = method.getAnnotation(SystemLog.class);
                log.setMODULE(systemlog.module());
                log.setMETHOD(systemlog.methods());
                try {
                    object = pjp.proceed();
                    long end = System.currentTimeMillis();
                    //将计算好的时间保存在实体中
                    log.setRSPONSE_DATA(""+(end-start));
                    log.setCOMMITE("执行成功!");
                    //保存进数据库
                    logservice.save(log);
                    /*System.out.println("没切完");*/
                } catch (Throwable e) {
                    // TODO Auto-generated catch block
                    long end = System.currentTimeMillis();
                    log.setRSPONSE_DATA(""+(end-start));
                    log.setCOMMITE("执行失败");
                    logservice.save(log);
                    /*System.out.println("切切切");*/
                }
            } else {//没有包含注解
                object = pjp.proceed();
            }
        } else { //不需要拦截直接执行
            object = pjp.proceed();
        }
        /*System.out.println("切完了");*/
        return object;
    }

}

数据库中新建一张表,用来存放日志信息,结构如下

当然还需要Domain类,数据库的表都在这了,实体类中一一对应起来写就可以了,然后写增删改查的方法

最后在生成一个查看日志的Controller类

package com.sure.crm.web.controller;

import com.sure.AjaxResult;
import com.sure.PageList;
import com.sure.crm.domain.LogEntity;
import com.sure.crm.query.LogEntityQuery;
import com.sure.crm.service.LogService;
import com.sure.crm.web.config.SystemLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.Map;


/**
 * 配置系统日志的Controller
 */
@CrossOrigin
@Controller
@RequestMapping("/log")
public class AopLogController {

    @Autowired
    private LogService logService;

    @ResponseBody
    @RequestMapping(value = "/queryPage",method = RequestMethod.PATCH)
    @SystemLog(module = "系统日志",methods = "日志管理-查询日志")
    public PageList<LogEntity> findLog(@RequestBody LogEntityQuery query){
        //这是我自己封装的一个类,一般不需要,根据各自情况来设置返回值
        PageList<LogEntity> pageList = logService.queryPage(query);
        return pageList;
    }
}

然后前台页面就访问请求,通过表格把数据展示出来即可完成

  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值