根据注解自动加入操作日志

需求:根据注解自动插入到操作日志

CREATE TABLE notice (
id bigint(20) NOT NULL AUTO_INCREMENT,
title varchar(255) DEFAULT NULL,
status int(11) DEFAULT NULL,
PRIMARY KEY (id)
)
CREATE TABLE logrecord (
id bigint(20) NOT NULL AUTO_INCREMENT,
username varchar(255) DEFAULT NULL,
type varchar(255) DEFAULT NULL,
remark varchar(255) DEFAULT NULL,
tableName varchar(255) DEFAULT NULL,
param text,
foreignKeyId bigint(20) DEFAULT NULL,
date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
)

依赖:

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
    </parent>
  <dependencies>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-aop</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
          <groupId>org.mybatis.spring.boot</groupId>
          <artifactId>mybatis-spring-boot-starter</artifactId>
          <version>1.3.2</version>
      </dependency>
      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
      </dependency>
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
      </dependency>
      <dependency>
          <groupId>io.springfox</groupId>
          <artifactId>springfox-swagger2</artifactId>
          <version>2.6.1</version>
      </dependency>
      <dependency>
          <groupId>io.springfox</groupId>
          <artifactId>springfox-swagger-ui</artifactId>
          <version>2.6.1</version>
      </dependency>
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid-spring-boot-starter</artifactId>
          <version>1.1.10</version>
      </dependency>
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>fastjson</artifactId>
          <version>1.2.54</version>
      </dependency>
  </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>lib</directory>
                <targetPath>BOOT-INF/lib/</targetPath>
                <includes>
                    <include>**/*.jar</include>
                </includes>
            </resource>
        </resources>
    </build>
@Data
public class LogRecord {
    private Long id;
    private String username;
    private String type;
    private Date date;
    private String tableName;
    private String remark;
    private String param;
    private Long foreignKeyId;
}
@Data
public class Notice {

    private int id;

    private String title;

    /**
     * 状态:1保存;2发布
     */
    private int status;
    private List<LogRecord> logRecords=new ArrayList<>();
}
public interface NoticeMapper  {
    void add(Notice notice);
    void delete(Long id);
    List<Notice> search(Notice notice);
}
public interface LogRecordMapper {
    void add(LogRecord logRecord);
}
<mapper namespace="com.study.dao.NoticeMapper">
    <resultMap id="resultMap" type="com.study.bean.Notice">
        <id column="id"  property="id"/>
        <result column="title"  property="title"/>
        <result column="status"  property="status"/>
        <collection property="logRecords" select="getLogRecordsNotice" column="id"> </collection>
    </resultMap>
    <insert id="add" keyProperty="id" useGeneratedKeys="true">
        insert into notice(title,status) values (#{title},#{status})
    </insert>
    <delete id="delete">
        delete from notice where id=#{id}
    </delete>
    <select id="search" resultMap="resultMap">
        select id,title,status from notice
    </select>
     <select id="getLogRecordsNotice" resultType="com.study.bean.LogRecord">
        select id,username,type,tableName,param,foreignKeyId,date,remark from logrecord where tableName='notice' and foreignKeyId=#{id}
    </select>
</mapper>
<mapper namespace="com.study.dao.LogRecordMapper">

    <insert id="add" keyProperty="id" useGeneratedKeys="true">
        insert into logrecord(username,type,tableName,param,foreignKeyId,date,remark) values (#{username},#{type},#{tableName},#{param},#{foreignKeyId},#{date},#{remark})
    </insert>

</mapper>
@Service
public class LogRecordService {
    @Autowired
    private LogRecordMapper logRecordMapper;
    public void add(LogRecord logRecord){
        logRecordMapper.add(logRecord);
    }

}
@Service
public class NoticeService {
    @Autowired
    private NoticeMapper noticeMapper;
    @Autowired
    private DataSourceTransactionManager manager;
    /**
     *切换
     */
    @ToLog(tableName = "notice")
    public void addMethod(Notice notice){
        add1(notice);
    }
    @Transactional
    public void add1(Notice notice) {
        noticeMapper.add(notice);
    }
    @Transactional
    public void add2(Notice notice) {
        noticeMapper.add(notice);
    }
    @Transactional
    @ToLog(tableName = "notice",type = "删除")
    public void delete(Long id) {
        noticeMapper.delete(id);
    }

    public List<Notice> search(Notice notice) {
        return noticeMapper.search(notice);
    }
}
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Documented
public @interface ToLog {
    String type() default "新增";
    String tableName() default "0";
}
@Aspect
@Component
@Slf4j
public class LogAOP {
    public static final ThreadLocal<LogRecord> THREAD_LOCAL=new ThreadLocal<>();
    //日志service注入
    @Autowired
    private LogRecordService logRecordService;
    //切点是注解ToLog
    @Pointcut(value = "@annotation(toLog)")
    public void cut(ToLog toLog){
    }
    //进入切点前封装对象进ThreadLocal
    @Before(value = "cut(toLog)")
    public void doBefore(JoinPoint joinPoint, ToLog toLog){
        LogRecord logRecord=new LogRecord();
        StringBuffer param = new StringBuffer();
        logRecord.setUsername("测试");//实际应从session取用户
        //从注解中取值
        logRecord.setTableName(toLog.tableName());
        logRecord.setType(toLog.type());
        try {
            log.info("------aop begin------");
            //反射+内省拿到切点上的方法参数
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            Parameter[] parameters = method.getParameters();
            Object[] args = joinPoint.getArgs();
            if (args != null) {
                for (int index = 0; index < args.length; index++) {
                    Object arg = args[index];
                    if (!(arg instanceof HttpServletRequest || arg instanceof HttpServletResponse)) {
                        Parameter parameter = parameters[index];
                        param.append(JSON.toJSON(arg));
                    }
                }
            }
            // 将request请求中的请求参数放入日志
            logRecord.setParam(param.toString());
        }catch (Exception e){
            e.printStackTrace();
           logRecord.setRemark("AOP ERROR"+e);
           log.error("AOP ERROR",e);
        }
        logRecord.setDate(new Date());
        THREAD_LOCAL.set(logRecord);
    }
    @AfterReturning(pointcut = "cut(toLog)", returning = "returnVal")
    public void doAfter(JoinPoint joinPoint, Object returnVal, ToLog toLog){
        //取ThreadLocal中的对象
        LogRecord logRecord = THREAD_LOCAL.get();
        try {
            //returnVal为被增强方法的返回值
            logRecord.setForeignKeyId((Long) returnVal);
        } catch (Exception e) {
            e.printStackTrace();
            logRecord.setRemark("AOP ERROR"+e);
            log.error("AOP ERROR",e);
        }
        log.info("-------aop end------");
        logRecordService.add(logRecord);
    }
}

完美

在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值