SpringBoot异步切面日志

SpringBoot异步切面日志


代码

@Target(ElementType.METHOD)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    /* 描述 */
    String desc() default "";
}
@Aspect
@Component
public class LogAspct {
    @Autowired
    private ApplicationContext applicationContext;

    /**
     *  1、execution 表达式主体
     *  2、第1个* 表示返回值类型  *表示所有类型
     *  3、某个个包名下的某个类名下的某个方法  *表示全部, 此处:com.hl.springbootdemo.controller包下所有的类中的所有的public方法
     *  6、(..) 表示方法参数,..表示任何参数
     */
//    @Pointcut("execution(public * com.hl.springbootdemo.controller.*.*(..))")
//    public void logPointCut(){}

    /**
     * 带有@Log的注解的方法
     * */
    @Pointcut("@annotation(com.hl.springbootdemo.anno.Log)")
    public void logPointCut(){}

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        try {
            Object result = point.proceed();
            return result;
        }catch (Exception e){
            throw e;
        }finally {
            long endTime = System.currentTimeMillis();
            Log aopLog = ((MethodSignature) point.getSignature()).getMethod().getAnnotation(Log.class);
            String desc = aopLog.desc();
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            String uri = request.getRequestURI();
            String ip = getIpAddr(request);
            // 异步事件
            LogAopEvent event = new LogAopEvent(this, desc, endTime - beginTime, ip, uri);
            applicationContext.publishEvent(event);
        }
    }

    /**
     * 获取请求ip
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request){
        String ipAddress = request.getHeader("x-forwarded-for");
        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if("127.0.0.1".equals(ipAddress) || "0:0:0:0:0:0:0:1".equals(ipAddress)){
                //根据网卡取本机配置的IP
                InetAddress inet=null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ipAddress= inet.getHostAddress();
            }
        }
        //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
        if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
            if(ipAddress.indexOf(",")>0){
                ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
            }
        }
        return ipAddress;
    }
}
public class LogAopEvent extends ApplicationEvent {
    private String desc;
    private long cost;
    private String ip;
    private String uri;

    public LogAopEvent(Object source, String desc, long cost, String ip, String uri) {
        super(source);
        this.desc = desc;
        this.cost = cost;
        this.ip = ip;
        this.uri = uri;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public long getCost() {
        return cost;
    }

    public void setCost(long cost) {
        this.cost = cost;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getUri() {
        return uri;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }
}
@Service
public class WriteLogService implements ApplicationListener<LogAopEvent> {

    @Override
    @Async
    public void onApplicationEvent(LogAopEvent event) {
       	// 此处可以将数据写入数据库或者做其他的操作
        System.out.println(event.getIp() + " - " + event.getDesc() + " cost:" + event.getCost());
    }
}
@RestController
public class TestController {
    @RequestMapping("add")
    @Log(desc = "新增用户")
    public String addUser(){
        String username = "小明";
        return "success";
    }
}

启动类上增加
@EnableAsync//支持异步
@Aspect //支持切面编程

总结

切面编程:将与业务无关但是重复性很强的代码可以抽离出来使用切面编程进行处理.
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值