Guice+aopalliance实现Aop之 日志记录

前言

由于我们开发中经常需要手动写请求参数以及方法的返回值打印 每个都写显得很繁琐所以今天我们主要使用Guice的注解注入对象功能以及加上aopalliance 的动态代理实现请求参数和响应参数的日志打印 方便我们查看日志信息 具体Guice介绍就不在此介绍不了解的可以通过一些不错Guice原理分析学习了解

业务代码模拟

  • 用户实体
package org.cloudcommon.guava.dto;

/**
 * @ClassName UserDTO
 * @Description: TODO
 * @Author xiaowu
 * @Date 2021/6/30
 * @Version V1.0
 **/
public class UserDTO {

    private String name;

    private Integer age;

    private Long userId;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    @Override
    public String toString() {
        return "UserDTO{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", userId=" + userId +
                '}';
    }
}
  • 业务层
package org.cloudcommon.guava.service;
import org.cloudcommon.guava.dto.UserDTO;
/**
 * @author xiaowu
 */
public interface IUserService {

    /**
     *  获取用户信息
     * @param userDTO
     * @return
     */
    UserDTO findUserDetail(UserDTO userDTO);
}

package org.cloudcommon.guava.service.impl;
import cn.hutool.core.lang.Console;
import org.cloudcommon.guava.dto.UserDTO;
import org.cloudcommon.guava.service.IUserService;
/**
 * @ClassName UserServiceImpl
 * @Description: TODO
 * @Author xiaowu
 * @Date 2021/6/30
 * @Version V1.0
 **/
public class UserServiceImpl implements IUserService {
    
    /**
     * 获取用户信息
     *
     * @param userDTO
     * @return
     */
    @Override
    public UserDTO findUserDetail(UserDTO userDTO) {
        userDTO.setAge(99);
        userDTO.setName("小五");
        Console.log("busness");
        return userDTO;
    }
}

拦截器实现代理

package org.cloudcommon.guava.interceptor;

import cn.hutool.core.lang.Console;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import com.google.gson.Gson;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
 * @ClassName LogAopInterceptor
 * @Description: aop 拦截器
 * @Author xiaowu
 * @Date 2021/6/30
 * @Version V1.0
 **/
public class LogAopInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        String threadName = Thread.currentThread().getName() + "_" + Thread.currentThread().getId();
        Console.log("requestData:请求方法名称:{}, 请求线程名称:{}, 请求参数:{}", methodInvocation.getMethod().getName(), threadName, methodInvocation.getArguments());
        try {
            Object proceed = methodInvocation.proceed();
            Console.log("responseData: 请求方法名称:{}, 请求线程名称:{}, 响应参数:{}", methodInvocation.getMethod().getName(), threadName, proceed);
            return proceed;
        } catch (Throwable e) {
            Console.log("ErrorData: 请求方法名称:{}, 请求线程名称:{}, 异常参数:{}", methodInvocation.getMethod().getName(), threadName, e);
            throw e;
        }
    }
}

Guice 实现拦截绑定

package org.cloudcommon.guava.config;

import com.google.inject.AbstractModule;
import com.google.inject.matcher.Matchers;
import org.cloudcommon.guava.interceptor.LogAopInterceptor;
import org.cloudcommon.guava.service.IUserService;

/**
 * @ClassName BaseModel
 * @Description: TODO
 * @Author 小五
 * @Date 2021/6/30
 * @Version V1.0
 **/
public class BaseModel extends AbstractModule {
    @Override
    protected void configure() {
        bindInterceptor(Matchers.subclassesOf(IUserService.class),Matchers.any(), new LogAopInterceptor());
    }
}

测试用例

package org.cloudcommon;

import com.google.inject.Guice;
import com.google.inject.Inject;
import org.cloudcommon.guava.config.BaseModel;
import org.cloudcommon.guava.dto.UserDTO;
import org.cloudcommon.guava.service.impl.UserServiceImpl;
import org.junit.Before;
import org.junit.Test;

/**
 * @ClassName TestSingleBean
 * @Description: TODO
 * @Author xiaowu
 * @Date 2021/6/30
 * @Version V1.0
 **/
public class TestSingleBean {

    @Before
    public void init() {
        Guice.createInjector(new BaseModel()).injectMembers(this);
    }

    @Inject
    private UserServiceImpl userService;

    @Test
    public void testAop() {
        UserDTO userDTO = new UserDTO();
        userDTO.setUserId(555L);
        userService.findUserDetail(userDTO);
    }
}

效果

requestData:请求方法名称:findUserDetail, 请求线程名称:main_1, 请求参数:[UserDTO{name='null', age=null, userId=555}]
busness
responseData: 请求方法名称:findUserDetail, 请求线程名称:main_1, 响应参数:UserDTO{name='小五', age=99, userId=555}

总结

通过上面方法我们可以很方便实现日志记录打印 后续有变化的需求通过bindInterceptor 绑定的参数 第一个参数 那些类需要记录,第二个参数是类中那些方法实现代理,第三个 是具体代理调用的拦截器。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜗牛乌龟一起走

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值