一,
package com.zhongan.business.hystrix;
import java.util.concurrent.Callable;
public class DelegatingUserContextCallable<V> implements Callable<V>{
private final Callable<V> delegate;
private UserContext originalUserContext;
public DelegatingUserContextCallable(Callable<V> delegate, UserContext userContext) {
super();
this.delegate = delegate;
this.originalUserContext = userContext;
}
@Override
public V call() throws Exception {
UserContextHolder.setContext(originalUserContext);
try{
return delegate.call();
}finally{
this.originalUserContext=null;
}
}
public static <V> Callable<V> create(Callable<V> delegate,UserContext userContext){
return new DelegatingUserContextCallable<V>(delegate, userContext);
}
}
二、
package com.zhongan.business.hystrix;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle;
import com.netflix.hystrix.strategy.properties.HystrixProperty;
public class ThreadLocalAwareStrategy extends HystrixConcurrencyStrategy{
private HystrixConcurrencyStrategy existingConcurrencyStrategy;
public ThreadLocalAwareStrategy(HystrixConcurrencyStrategy existingConcurrencyStrategy){
this.existingConcurrencyStrategy=existingConcurrencyStrategy;
}
@Override
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize){
return existingConcurrencyStrategy!=null?existingConcurrencyStrategy.getBlockingQueue(maxQueueSize):super.getBlockingQueue(maxQueueSize);
}
@Override
public <T> HystrixRequestVariable<T> getRequestVariable(HystrixRequestVariableLifecycle<T> rv){
return existingConcurrencyStrategy!=null?existingConcurrencyStrategy.getRequestVariable(rv):super.getRequestVariable(rv);
}
@Override
public ThreadPoolExecutor getThreadPool(final HystrixThreadPoolKey threadPoolKey, HystrixProperty corePoolSize, HystrixProperty maximumPoolSize, HystrixProperty keepAliveTime, TimeUnit unit, BlockingQueue workQueue) {
return existingConcurrencyStrategy!=null?existingConcurrencyStrategy.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue):super.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
public ThreadPoolExecutor getThreadPool(final HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) {
return existingConcurrencyStrategy!=null?existingConcurrencyStrategy.getThreadPool(threadPoolKey, threadPoolProperties):super.getThreadPool(threadPoolKey, threadPoolProperties);
}
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable){
return existingConcurrencyStrategy!=null?existingConcurrencyStrategy.wrapCallable(new DelegatingUserContextCallable<T>(callable, UserContextHolder.getContext())):super.wrapCallable(new DelegatingUserContextCallable<T>(callable, UserContextHolder.getContext()));
}
}
三、
package com.zhongan.business.hystrix;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
@Configuration
public class ThreadLocalConfiguration {
@Autowired(required=false)
private HystrixConcurrencyStrategy existingConcurrencyStrategy;
@PostConstruct
public void init(){
HystrixEventNotifier eventNotifier=HystrixPlugins.getInstance().getEventNotifier();
HystrixMetricsPublisher metricsPublisher=HystrixPlugins.getInstance().getMetricsPublisher();
HystrixPropertiesStrategy propertiesStrategy=HystrixPlugins.getInstance().getPropertiesStrategy();
HystrixCommandExecutionHook commandExecutionHook=HystrixPlugins.getInstance().getCommandExecutionHook();
HystrixPlugins.reset();
HystrixPlugins.getInstance().registerConcurrencyStrategy(new ThreadLocalAwareStrategy(existingConcurrencyStrategy));
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
}
}
四、
package com.zhongan.business.hystrix;
import org.springframework.stereotype.Component;
@Component
public class UserContext {
public static final String LOG_SERIAL_NUMBER = "logSerialNumber";
private String logSerialNumber= new String();
public String getLogSerialNumber() {
return logSerialNumber;
}
public void setLogSerialNumber(String logSerialNumber) {
this.logSerialNumber = logSerialNumber;
}
}
五、
package com.zhongan.business.hystrix;
import org.springframework.util.Assert;
public class UserContextHolder {
private static final ThreadLocal<UserContext> userContext=new ThreadLocal<UserContext>();
public static final UserContext getContext(){
UserContext context=userContext.get();
if(context==null){
context=createEmptyContext();
userContext.set(context);
}
return userContext.get();
}
public static final void setContext(UserContext context){
Assert.notNull(context,"Only non-null UserContext instances are permitted");
userContext.set(context);
}
public static final UserContext createEmptyContext() {
return new UserContext();
}
}