基於註解
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
})
// com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect.CommandMetaHolderFactory
private static class CommandMetaHolderFactory extends MetaHolderFactory {
@Override
public MetaHolder create(Object proxy, Method method, Object obj, Object[] args, final ProceedingJoinPoint joinPoint) {
// 獲取註解
HystrixCommand hystrixCommand = method.getAnnotation(HystrixCommand.class);
ExecutionType executionType = ExecutionType.getExecutionType(method.getReturnType());
/
MetaHolder.Builder builder = metaHolderBuilder(proxy, method, obj, args, joinPoint);
if (isCompileWeaving()) {
builder.ajcMethod(getAjcMethodFromTarget(joinPoint));
}
return builder.defaultCommandKey(method.getName())
.hystrixCommand(hystrixCommand) // init hystrixCommand
.observableExecutionMode(hystrixCommand.observableExecutionMode())
.executionType(executionType)
.observable(ExecutionType.OBSERVABLE == executionType)
.build();
}
}
基於MetaHolder創建Command
@Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()")
public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable {
Method method = getMethodFromTarget(joinPoint);
Validate.notNull(method, "failed to get method from joinPoint: %s", joinPoint);
if (method.isAnnotationPresent(HystrixCommand.class) && method.isAnnotationPresent(HystrixCollapser.class)) {
throw new IllegalStateException("method cannot be annotated with HystrixCommand and HystrixCollapser " +
"annotations at the same time");
}
MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method));
MetaHolder metaHolder = metaHolderFactory.create(joinPoint);
// 創建commond
HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder);
ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ?
metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType();
Object result;
try {
if (!metaHolder.isObservable()) {
// 執行
result = CommandExecutor.execute(invokable, executionType, metaHolder);
} else {
result = executeObservable(invokable, executionType, metaHolder);
}
} catch (HystrixBadRequestException e) {
throw e.getCause();
} catch (HystrixRuntimeException e) {
throw hystrixRuntimeExceptionToThrowable(metaHolder, e);
}
return result;
}
//com.netflix.hystrix.contrib.javanica.command.HystrixCommandFactory#create
//初始化的同時將配置傳遞給父類com.netflix.hystrix.AbstractCommand
public HystrixInvokable create(MetaHolder metaHolder) {
HystrixInvokable executable;
if (metaHolder.isCollapserAnnotationPresent()) {
executable = new CommandCollapser(metaHolder);
} else if (metaHolder.isObservable()) {
executable = new GenericObservableCommand(HystrixCommandBuilderFactory.getInstance().create(metaHolder));
} else {
executable = new GenericCommand(HystrixCommandBuilderFactory.getInstance().create(metaHolder));
}
return executable;
}
配置信息讀取
public HystrixCommandBuilder create(MetaHolder metaHolder) {
return create(metaHolder, Collections.<HystrixCollapser.CollapsedRequest<Object, Object>>emptyList());
}
public <ResponseType> HystrixCommandBuilder create(MetaHolder metaHolder, Collection<HystrixCollapser.CollapsedRequest<ResponseType, Object>> collapsedRequests) {
validateMetaHolder(metaHolder);
return HystrixCommandBuilder.builder()
.setterBuilder(createGenericSetterBuilder(metaHolder))
.commandActions(createCommandActions(metaHolder))
.collapsedRequests(collapsedRequests)
.cacheResultInvocationContext(createCacheResultInvocationContext(metaHolder))
.cacheRemoveInvocationContext(createCacheRemoveInvocationContext(metaHolder))
.ignoreExceptions(metaHolder.getCommandIgnoreExceptions())
.executionType(metaHolder.getExecutionType())
.build();
}
private GenericSetterBuilder createGenericSetterBuilder(MetaHolder metaHolder) {
GenericSetterBuilder.Builder setterBuilder = GenericSetterBuilder.builder()
.groupKey(metaHolder.getCommandGroupKey())
.threadPoolKey(metaHolder.getThreadPoolKey())
.commandKey(metaHolder.getCommandKey())
.collapserKey(metaHolder.getCollapserKey())
.commandProperties(metaHolder.getCommandProperties())
.threadPoolProperties(metaHolder.getThreadPoolProperties())
.collapserProperties(metaHolder.getCollapserProperties());
if (metaHolder.isCollapserAnnotationPresent()) {
setterBuilder.scope(metaHolder.getHystrixCollapser().scope());
}
return setterBuilder.build();
}
基於配置文件
// com.netflix.hystrix.HystrixCommandProperties
this.executionTimeoutInMilliseconds = getProperty(propertyPrefix, key, "execution.isolation.thread.timeoutInMilliseconds", builder.getExecutionIsolationThreadTimeoutInMilliseconds(), default_executionTimeoutInMilliseconds);
private static HystrixProperty<Integer> getProperty(String propertyPrefix, HystrixCommandKey key, String instanceProperty, Integer builderOverrideValue, Integer defaultValue) {
return forInteger()
.add(propertyPrefix + ".command." + key.name() + "." + instanceProperty, builderOverrideValue)
.add(propertyPrefix + ".command.default." + instanceProperty, defaultValue)
.build();
}
//com.netflix.hystrix.strategy.properties.HystrixPropertiesChainedProperty#getDynamicProperty
private static <T> HystrixDynamicProperty<T>
getDynamicProperty(String propName, T defaultValue, Class<T> type) {
HystrixDynamicProperties properties = HystrixPlugins.getInstance().getDynamicProperties();
HystrixDynamicProperty<T> p =
HystrixDynamicProperties.Util.getProperty(properties, propName, defaultValue, type);
return p;
}
基於archaius的屬性讀取
public static DynamicPropertyFactory getInstance() {
if (config == null) {
synchronized (ConfigurationManager.class) {
if (config == null) {
// ConfigurationManager中有spring配置文件中的屬性信息
AbstractConfiguration configFromManager = ConfigurationManager.getConfigInstance();
if (configFromManager != null) {
initWithConfigurationSource(configFromManager);
initializedWithDefaultConfig = !ConfigurationManager.isConfigurationInstalled();
logger.info("DynamicPropertyFactory is initialized with configuration sources: " + configFromManager);
}
}
}
}
return instance;
}