TheadLocal
客户端发送的每次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<Long> 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")类型确实是LongLong 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*/@Overridepublic 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*/@Overridepublic 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());}
}
第五步,删除之前写的创建、更新时间等相关代码,让其自动填充