3

JsonSerializer我的Spring 项目中有一个简单的:

public class JsonDateTimeSerializer extends JsonSerializer<Date> {
    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider sp) throws IOException {
        gen.writeString(DATE_FORMAT.format(value));
    }
}

并像这样使用它:

@JsonSerialize(using = JsonDateTimeSerializer.class)
public Date getDate() {
    return date;
}

我是否必须注意线程安全并进行DATE_FORMAT同步(因为SimpleDateFormat不是线程安全的)?我不确定究竟是如何@JsonSerialize工作的——它是否在所有线程中只创建一个序列化实例?或者它是否为每个转换创建单独的实例?

4

2 回答 2

4

如果JsonDateTimeSerializer.serialize可能从多个线程调用,那么这种使用SimpleDateFormat是不安全的。在另一个答案SimpleDateFormat中很好地解释了避免低效同步的常用方法 。适应您的用例:

public class JsonDateTimeSerializer extends JsonSerializer<Date> {

    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };

    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider sp) throws IOException {
        gen.writeString(formatter.get().format(value));
    }
}
于 2014-09-05T07:56:50.733 回答
1

当杰克逊第一次看到你的类型时,(取决于类型)它将为每个属性构建一个BeanSerializer带有适当s 的 a。JsonSerializerBeanSerializer被缓存并重用于相同的未来序列化Type

因此,JsonDateTimeSerializer(每个类型)的单个实例,将被注册到JsonDateTimeSerializer,将被重用于所有序列化。ObjectMapper因此,如果您计划跨多个线程使用它,它必须是线程安全的。(你应该因为它ObjectMapper本身是线程安全的。)

于 2014-09-06T02:37:05.573 回答