关于threadLocal用法推荐
package org.apache.ibatis.executor;
/**
* 错误上下文
*
* @author Clinton Begin
*/
public class ErrorContext {
private static final String LINE_SEPARATOR = System.lineSeparator();
/**线程级别的缓存,并且初始化创建了{@link ErrorContext}对象*/
private static final ThreadLocal<ErrorContext> LOCAL = ThreadLocal.withInitial(ErrorContext::new);
/***/
private ErrorContext stored;
private String resource;
private String activity;
private String object;
private String message;
private String sql;
private Throwable cause;
private ErrorContext() {
}
/**
* 获取当前线程中的{@link ErrorContext}对象
*
* @return
*/
public static ErrorContext instance() {
return LOCAL.get();
}
/**
* 存储
* @return
*/
public ErrorContext store() {
ErrorContext newContext = new ErrorContext();
newContext.stored = this;
LOCAL.set(newContext);
return LOCAL.get();
}
/**
* 重新调用
* @return
*/
public ErrorContext recall() {
if (stored != null) {
LOCAL.set(stored);
stored = null;
}
return LOCAL.get();
}
/**
* 设置对象的resource属性
*
* @param resource
* @return {@link ErrorContext}
*/
public ErrorContext resource(String resource) {
this.resource = resource;
return this;
}
/**
* 设置对象activity属性
* @param activity
* @return
*/
public ErrorContext activity(String activity) {
this.activity = activity;
return this;
}
/**
* 设置对象object属性
*
* @param object
* @return
*/
public ErrorContext object(String object) {
this.object = object;
return this;
}
/**
* 设置对象的message属性
*
* @param message
* @return
*/
public ErrorContext message(String message) {
this.message = message;
return this;
}
/**
* 设置对象的sql属性
*
* @param sql
* @return
*/
public ErrorContext sql(String sql) {
this.sql = sql;
return this;
}
/**
* 设置对象的cause属性
*
* @param cause
* @return
*/
public ErrorContext cause(Throwable cause) {
this.cause = cause;
return this;
}
/**
* 重置
*
* @return
*/
public ErrorContext reset() {
resource = null;
activity = null;
object = null;
message = null;
sql = null;
cause = null;
LOCAL.remove();
return this;
}
@Override
public String toString() {
StringBuilder description = new StringBuilder();
// message
if (this.message != null) {
description.append(LINE_SEPARATOR);
description.append("### ");
description.append(this.message);
}
// resource
if (resource != null) {
description.append(LINE_SEPARATOR);
description.append("### The error may exist in ");
description.append(resource);
}
// object
if (object != null) {
description.append(LINE_SEPARATOR);
description.append("### The error may involve ");
description.append(object);
}
// activity
if (activity != null) {
description.append(LINE_SEPARATOR);
description.append("### The error occurred while ");
description.append(activity);
}
// sql
if (sql != null) {
description.append(LINE_SEPARATOR);
description.append("### SQL: ");
description.append(sql.replace('\n', ' ').replace('\r', ' ').replace('\t', ' ').trim());
}
// cause
if (cause != null) {
description.append(LINE_SEPARATOR);
description.append("### Cause: ");
description.append(cause.toString());
}
return description.toString();
}
}
BaseStatementHandler
protected void generateKeys(Object parameter) {
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
ErrorContext.instance().store();
keyGenerator.processBefore(executor, mappedStatement, null, parameter);
ErrorContext.instance().recall();
}