Spring如何基于aop实现操作日志功能
程序员文章站
2022-06-22 11:49:56
1. 在pom中添加所需依赖创建一个springboot工程,添加所需要的依赖,持久化用的是mybatis org.sp...
1. 在pom中添加所需依赖
创建一个springboot工程,添加所需要的依赖,持久化用的是mybatis
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <!--springboot aop依赖--> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-aop</artifactid> </dependency> <!--mybatis--> <dependency> <groupid>org.mybatis.spring.boot</groupid> <artifactid>mybatis-spring-boot-starter</artifactid> <version>2.1.3</version> </dependency> <!--mysql连接--> <dependency> <groupid>mysql</groupid> <artifactid>mysql-connector-java</artifactid> <version>8.0.19</version> <scope>runtime</scope> </dependency> <!--lombok--> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> <optional>true</optional> </dependency>
2. 创建日志实体类
import lombok.data; import java.io.serializable; @data public class adminlog implements serializable { private static final long serialversionuid = -291495801959706565l; private integer id; //日志记录id private integer userid;//操作人id private string username;//操作人name private string loginip;//登录ip private int type; private string url; private string operation; private string createtime; private string remark; }
3. 自定义log注解
import java.lang.annotation.*; /** * 自定义日志注解 */ @target(elementtype.method) //注解防止位置 @retention(retentionpolicy.runtime)//运行时可见 @documented //生成文档 public @interface mylog { string operation() default ""; int type(); }
4. 创建aop切面处理类
import cn.***.springaopdemo.anno.mylog; import cn.***.springaopdemo.dao.mylogmapper; import cn.***.springaopdemo.pojo.admin; import cn.***.springaopdemo.pojo.adminlog; import org.apache.logging.log4j.logmanager; import org.apache.logging.log4j.logger; import org.aspectj.lang.joinpoint; import org.aspectj.lang.annotation.aspect; import org.aspectj.lang.annotation.before; 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; /** * 切面处理类 */ @aspect @component public class syslogaspect { /** * 使用log4j2把一些信息打印在控制台上面 */ private static final logger log = logmanager.getlogger(syslogaspect.class); @autowired private mylogmapper mylogmapper; //定义切点 @pointcut //在注解的位置切入代码 @pointcut("@annotation(cn.***.springaopdemo.anno.mylog)") public void logpointcut() { } //切面 配置为前置通知 @before("logpointcut()") public void saveoperation(joinpoint joinpoint) { log.info("---------------接口日志记录---------------"); //创建一个日志对象 adminlog adminlog = new adminlog(); //获取切面织处入点的方法 methodsignature signature = (methodsignature) joinpoint.getsignature(); //获取切入点所在的方法 method method = signature.getmethod(); //获取操作日志的属性值 mylog mylog = method.getannotation(mylog.class); if (mylog != null) { //操作事件 string operation = mylog.operation(); adminlog.setoperation(operation); //日志类型 int type = mylog.type(); adminlog.settype(type); log.info("operation=" + operation + ",type=" + type); } //获取url httpservletrequest request = ((servletrequestattributes) requestcontextholder.getrequestattributes()).getrequest(); string requesturl = request.getrequesturi().tostring(); adminlog.seturl(requesturl); //获取客户端ip string ip = request.getremoteaddr(); adminlog.setloginip(ip); //获取操作人账号、姓名(需要提前将用户信息保存到session) admin admin = (admin) request.getsession().getattribute("admin"); if (admin != null) { integer id = admin.getid(); string name = admin.getname(); adminlog.setuserid(id); adminlog.setusername(name); } log.info("url=" + requesturl + ",ip=" + ip); //调用service保存operation实体类到数据库 //可以在这设置id,因为是测试,这里就使用的是数据库的自增id mylogmapper.insertlog(adminlog); } }
5. mapper层把日志数据存储到mysql数据库中
mapper接口
import cn.***.springaopdemo.pojo.adminlog; import java.util.list; public interface mylogmapper { void insertlog(adminlog adminlog); }
mapper.xml文件
<?xml version="1.0" encoding="utf-8" ?> <!doctype mapper public "-//mybatis.org//dtd mapper 3.0//en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.***.springaopdemo.dao.mylogmapper"> <insert id="insertlog" parametertype="cn.***.springaopdemo.pojo.adminlog"> insert into admin_log (user_id,user_name,loginip,type,url,operation,createtime,remark) values (#{userid},#{username},#{loginip},#{type},#{url},#{operation},now(),#{remark}) </insert> </mapper>
6. 测试
先直接登录用户,因为是测试,直接从数据库中获取后登录,把admin存储到session中
import cn.***.springaopdemo.pojo.admin; import cn.***.springaopdemo.service.iadminservice; import org.apache.logging.log4j.logmanager; import org.apache.logging.log4j.logger; import org.springframework.beans.factory.annotation.autowired; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.restcontroller; import javax.servlet.http.httpservletrequest; import java.util.list; @restcontroller @requestmapping("/admin") public class admincontroller { private static final logger log = logmanager.getlogger(admincontroller.class); //中间service层可以省略,直接通过mapper接口操作数据即可 @autowired private iadminservice adminservice; @requestmapping("/login") public admin login(httpservletrequest request) { list<admin> adminlist = adminservice.findalladmin(); admin admin = adminlist.get(0); request.getsession().setattribute("admin",admin ); return admin; } }
在浏览器中输入localhost:8080/admin/login,可以看到登录的admin
进行插入和查询操作,插入数据直接通过后台提供
import cn.***.springaopdemo.anno.mylog; import cn.***.springaopdemo.pojo.type; import cn.***.springaopdemo.service.itypeservice; import org.apache.logging.log4j.logmanager; import org.apache.logging.log4j.logger; import org.springframework.beans.factory.annotation.autowired; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.restcontroller; import java.util.arraylist; import java.util.list; @restcontroller @requestmapping("/type") public class typecontroller { private static final logger log = logmanager.getlogger(typecontroller.class); @autowired private itypeservice typeservice; @mylog(operation = "增加书籍类型", type = 2) @requestmapping("/add") public void inserttype() { list<type> typelist = new arraylist<>(); type type = new type(); type.setname("自然科学"); typelist.add(type); typeservice.addtypelist(typelist); log.info("添加书籍类型" + type.getname()); } @mylog(operation = "查询所有书籍类型", type = 1) @requestmapping("/findall") public list<type> findalltype() { list<type> typelist = typeservice.findalltype(); log.info("查询所有书籍类型"); return typelist; } }
在浏览器中输入localhost:8080/type/add,后台日志打印记录
再输入查询请求localhost:8080/type/findall,获得查询出的分类
查看数据库是否添加成功
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Spring Cloud Gateway重试机制原理解析
下一篇: jQuery选择器&事件---2