需求:定时任务扫描,反射调用目的对象,但是,方法的传参不是固定的。
方案一:将方法参数存成JSON字符串,然后JSON反序列化成对象,然后反射调用
目的方法时如许的:- CommandResp sendXXX(BaseCommandApiDTO<XXX> baseCommandApiDTO);
复制代码 方式一:FastJson- Class mainBody = Class.forName(entity.getMainBodyType());
- ParameterizedTypeImpl parameterizedType = new ParameterizedTypeImpl(new Type[]{mainBody}, null, BaseCommandApiDTO.class);
- Object obj = JSON.parseObject(entity.getMsgText(), parameterizedType);
- CommandResp resp = ReflectUtil.invoke(serviceObj, methodName, obj);
复制代码 方式二:Jackson- public class ObjectMapperHolder {
- private static final ObjectMapper objectMapper = new ObjectMapper();
- public static ObjectMapper getObjectMapper() {
- objectMapper.registerModule(new Jdk8Module());
- objectMapper.registerModule(new JavaTimeModule());
- return objectMapper;
- }
- }
- ObjectMapper mapper = ObjectMapperHolder.getObjectMapper();
- JavaType javaType = mapper.getTypeFactory().constructParametricType(BaseCommandApiDTO.class, mainBody);
- Object obj = mapper.readValue(entity.getMsgText(), javaType);
- CommandResp resp = ReflectUtil.invoke(serviceObj, methodName, obj);
复制代码 实践中发现,这两种方式容易导致OOM
方案二:直接将参数对象存到数据库中
数据库对应字段设置BLOB类型(这里设置的是MEDIUMBLOB) ,对应的java字段类型是byte[]- // 写入对象
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(bos);
- oos.writeObject(baseCommandApiDTO);
- oos.flush();
- byte[] data = bos.toByteArray();
- // 读取对象
- ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(entity.getMsgObj()));
- Object obj = ois.readObject();
复制代码 末了的末了,优化建议:
1、尽量不要在数据库中存json字符串,如果非要存,建议字段类型设置为json,如许可以节省空间。由于你无法控制json字符串的长度,所以长度设置是个问题,另外json反序列化比较占内存。
2、长度很大的字段(比如blob类型的)建议单独存一张关联表
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |