客户端发送的每次http请求,在服务端都会分配新的线程。因此登录检查过滤器、controller、元数据对象处理器属于一个线程。
TheadLocal是线程的局部变量:

TheadLocal常用方法:

如何在元数据对象处理器中获取当前登录用户的id?
因为登录检查过滤器、controller、元数据对象处理器属于一个线程,所以可以在filter中获取登录用户的id,set到ThreadLocal中,在元数据处理器中get到线程局部变量ThreadLocal的值。
第一步,实体类注解:
- @TableField(fill = FieldFill.INSERT) //插入时填充字段
- private LocalDateTime createTime;
-
- @TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时填充字段
- private LocalDateTime updateTime;
-
- @TableField(fill = FieldFill.INSERT) //插入时填充字段
- private Long createUser;
-
- @TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时填充字段
- private Long updateUser;
第二步,封装基于ThreadLocal的工具类
在common包下:
- /**
- * 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id
- */
- public class BaseContext {
- private static ThreadLocal
threadLocal = new ThreadLocal<>(); -
- /**
- * 设置值
- * @param id
- */
- public static void setCurrentId(Long id){
- threadLocal.set(id);
- }
-
- /**
- * 获取值
- * @return
- */
- public static Long getCurrentId(){
- return threadLocal.get();
- }
- }
第三步,登录检查过滤器把id加到ThreadLocal
- //4、判断登录状态,如果已登录,则直接放行
- if(request.getSession().getAttribute("employee") != null){
- log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
- //这里要强转,虽然request.getSession().getAttribute("employee")类型确实是Long
- Long empId = (Long) request.getSession().getAttribute("employee");
- BaseContext.setCurrentId(empId);
-
- filterChain.doFilter(request,response);
- return;
- }
第四步,自定义元数据对象处理器,获取ThreadLocal的id
在common包下:
- /**
- * 自定义元数据对象处理器
- */
- @Component
- @Slf4j
- public class MyMetaObjectHandler implements MetaObjectHandler {
- /**
- * 插入操作,自动填充
- * @param metaObject
- */
- @Override
- public void insertFill(MetaObject metaObject) {
- log.info("公共字段自动填充[insert]...");
- log.info(metaObject.toString());
- //第一个参数属性名,第二个参数自动填充的值
- metaObject.setValue("createTime", LocalDateTime.now());
- metaObject.setValue("updateTime",LocalDateTime.now());
- metaObject.setValue("createUser",BaseContext.getCurrentId());
- metaObject.setValue("updateUser",BaseContext.getCurrentId());
- }
-
- /**
- * 更新操作,自动填充
- * @param metaObject
- */
- @Override
- public void updateFill(MetaObject metaObject) {
- log.info("公共字段自动填充[update]...");
- log.info(metaObject.toString());
-
- long id = Thread.currentThread().getId();
- log.info("线程id为:{}",id);
-
- metaObject.setValue("updateTime",LocalDateTime.now());
- metaObject.setValue("updateUser",BaseContext.getCurrentId());
- }
- }
第五步,删除之前写的创建、更新时间等相关代码,让其自动填充