原由是这样的,原先代码里copyProperties用的是 org.apache.commons.beanutils.BeanUtils,奈何这位老哥不太给力,source里的Date类型如果为空的话会报错。于是给改用了org.springframework.beans.BeanUtils; 结果线上发生了一个匪夷所思的问题。看下面代码:
Subject subject = SecurityUtils.getSubject(); Object principal = subject.getPrincipal(); log.info("principals is {}",JsonUtil.toJSONString(subject.getPrincipals().asSet().toArray())); if(principal != null) { ShopguideUser user=(ShopguideUser)principal; log.info("user = {}", JsonUtil.toJSONString(user)); BeanUtils.copyProperties(userInfo,user); ShopguideUserAccount account = accountService.getUserAccount(user.getId()); BeanUtils.copyProperties(account,userInfo ); return userInfo;
我这里因为想统一通过dubbo的filter传一些参数:
@Activate(group = {Constants.CONSUMER},order = -10000) @Slf4j public class ConsumerFilter implements Filter { @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { try { // RpcInvocation invocation1 = (RpcInvocation) invocation; Subject subject = SecurityUtils.getSubject(); ShopguideUser user = null; Object principal = subject.getPrincipal(); if(!subject.isAuthenticated()) { log.info("not authenticated principal = {}",principal); }else{ log.info("authenticated principal = {}",principal); } if(principal != null) { log.info("principal = {}", JsonUtil.toJSONString(principal)); log.info("principals is {}",JsonUtil.toJSONString(subject.getPrincipals().asSet().toArray())); user=(ShopguideUser)principal; RpcContext.getContext().setAttachment( Constant.AUTH_USER, user.getId().toString()); }
但这上面的principal明明有值,到了ConsumerFilter的principal就是个空对象{}了? 因为运行这两段程序绝对是在一个线程里发生的。怎么principal平白无故被改了?原来坑爹的是spring的BeanUtils的参数和apache的是相反的,user对象被覆盖了,变成了空对象!血的教训。