温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

spring cloud中FeignClientBuilder的用法

发布时间:2021-07-01 11:57:31 来源:亿速云 阅读:1193 作者:chen 栏目:大数据

这篇文章主要讲解了“spring cloud中FeignClientBuilder的用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“spring cloud中FeignClientBuilder的用法”吧!

本文主要研究一下spring cloud的FeignClientBuilder

FeignClientBuilder

spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/FeignClientBuilder.java

public class FeignClientBuilder {

	private final ApplicationContext applicationContext;

	public FeignClientBuilder(final ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

	public <T> Builder<T> forType(final Class<T> type, final String name) {
		return new Builder<>(this.applicationContext, type, name);
	}

	/**
	 * Builder of feign targets.
	 *
	 * @param <T> type of target
	 */
	public static final class Builder<T> {

		private FeignClientFactoryBean feignClientFactoryBean;

		private Builder(final ApplicationContext applicationContext, final Class<T> type,
				final String name) {
			this.feignClientFactoryBean = new FeignClientFactoryBean();

			this.feignClientFactoryBean.setApplicationContext(applicationContext);
			this.feignClientFactoryBean.setType(type);
			this.feignClientFactoryBean.setName(FeignClientsRegistrar.getName(name));
			this.feignClientFactoryBean.setContextId(FeignClientsRegistrar.getName(name));
			// preset default values - these values resemble the default values on the
			// FeignClient annotation
			this.url("").path("").decode404(false).fallback(void.class)
					.fallbackFactory(void.class);
		}

		public Builder url(final String url) {
			this.feignClientFactoryBean.setUrl(FeignClientsRegistrar.getUrl(url));
			return this;
		}

		public Builder contextId(final String contextId) {
			this.feignClientFactoryBean.setContextId(contextId);
			return this;
		}

		public Builder path(final String path) {
			this.feignClientFactoryBean.setPath(FeignClientsRegistrar.getPath(path));
			return this;
		}

		public Builder decode404(final boolean decode404) {
			this.feignClientFactoryBean.setDecode404(decode404);
			return this;
		}

		public Builder fallback(final Class<T> fallback) {
			FeignClientsRegistrar.validateFallback(fallback);
			this.feignClientFactoryBean.setFallback(fallback);
			return this;
		}

		public Builder fallbackFactory(final Class<T> fallbackFactory) {
			FeignClientsRegistrar.validateFallbackFactory(fallbackFactory);
			this.feignClientFactoryBean.setFallbackFactory(fallbackFactory);
			return this;
		}

		/**
		 * @param <T> the target type of the Feign client to be created
		 * @return the created Feign client
		 */
		public <T> T build() {
			return this.feignClientFactoryBean.getTarget();
		}

	}

}
  • FeignClientBuilder提供了forType静态方法用于创建Builder;Builder的构造器创建了FeignClientFactoryBean,其build方法使用FeignClientFactoryBean的getTarget()来创建目标feign client

实例

public class FeignClientBuilderTests {

	@Rule
	public ExpectedException thrown = ExpectedException.none();

	private FeignClientBuilder feignClientBuilder;

	private ApplicationContext applicationContext;

	private static Object getDefaultValueFromFeignClientAnnotation(
			final String methodName) {
		final Method method = ReflectionUtils.findMethod(FeignClient.class, methodName);
		return method.getDefaultValue();
	}

	private static void assertFactoryBeanField(final FeignClientBuilder.Builder builder,
			final String fieldName, final Object expectedValue) {
		final Field factoryBeanField = ReflectionUtils
				.findField(FeignClientBuilder.Builder.class, "feignClientFactoryBean");
		ReflectionUtils.makeAccessible(factoryBeanField);
		final FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) ReflectionUtils
				.getField(factoryBeanField, builder);

		final Field field = ReflectionUtils.findField(FeignClientFactoryBean.class,
				fieldName);
		ReflectionUtils.makeAccessible(field);
		final Object value = ReflectionUtils.getField(field, factoryBean);
		assertThat(value).as("Expected value for the field '" + fieldName + "':")
				.isEqualTo(expectedValue);
	}

	@Before
	public void setUp() {
		this.applicationContext = Mockito.mock(ApplicationContext.class);
		this.feignClientBuilder = new FeignClientBuilder(this.applicationContext);
	}

	@Test
	public void safetyCheckForNewFieldsOnTheFeignClientAnnotation() {
		final List<String> methodNames = new ArrayList();
		for (final Method method : FeignClient.class.getMethods()) {
			methodNames.add(method.getName());
		}
		methodNames.removeAll(
				Arrays.asList("annotationType", "value", "serviceId", "qualifier",
						"configuration", "primary", "equals", "hashCode", "toString"));
		Collections.sort(methodNames);
		// If this safety check fails the Builder has to be updated.
		// (1) Either a field was removed from the FeignClient annotation and so it has to
		// be removed
		// on this builder class.
		// (2) Or a new field was added and the builder class has to be extended with this
		// new field.
		assertThat(methodNames).containsExactly("contextId", "decode404", "fallback",
				"fallbackFactory", "name", "path", "url");
	}

	@Test
	public void forType_preinitializedBuilder() {
		// when:
		final FeignClientBuilder.Builder builder = this.feignClientBuilder
				.forType(FeignClientBuilderTests.class, "TestClient");

		// then:
		assertFactoryBeanField(builder, "applicationContext", this.applicationContext);
		assertFactoryBeanField(builder, "type", FeignClientBuilderTests.class);
		assertFactoryBeanField(builder, "name", "TestClient");
		assertFactoryBeanField(builder, "contextId", "TestClient");

		// and:
		assertFactoryBeanField(builder, "url",
				getDefaultValueFromFeignClientAnnotation("url"));
		assertFactoryBeanField(builder, "path",
				getDefaultValueFromFeignClientAnnotation("path"));
		assertFactoryBeanField(builder, "decode404",
				getDefaultValueFromFeignClientAnnotation("decode404"));
		assertFactoryBeanField(builder, "fallback",
				getDefaultValueFromFeignClientAnnotation("fallback"));
		assertFactoryBeanField(builder, "fallbackFactory",
				getDefaultValueFromFeignClientAnnotation("fallbackFactory"));
	}

	@Test
	public void forType_allFieldsSetOnBuilder() {
		// when:
		final FeignClientBuilder.Builder builder = this.feignClientBuilder
				.forType(FeignClientBuilderTests.class, "TestClient").decode404(true)
				.fallback(Object.class).fallbackFactory(Object.class).path("Path/")
				.url("Url/");

		// then:
		assertFactoryBeanField(builder, "applicationContext", this.applicationContext);
		assertFactoryBeanField(builder, "type", FeignClientBuilderTests.class);
		assertFactoryBeanField(builder, "name", "TestClient");

		// and:
		assertFactoryBeanField(builder, "url", "http://Url/");
		assertFactoryBeanField(builder, "path", "/Path");
		assertFactoryBeanField(builder, "decode404", true);
		assertFactoryBeanField(builder, "fallback", Object.class);
		assertFactoryBeanField(builder, "fallbackFactory", Object.class);
	}

	@Test
	public void forType_build() {
		// given:
		Mockito.when(this.applicationContext.getBean(FeignContext.class))
				.thenThrow(new ClosedFileSystemException()); // throw an unusual exception
																// in the
																// FeignClientFactoryBean
		final FeignClientBuilder.Builder builder = this.feignClientBuilder
				.forType(TestClient.class, "TestClient");

		// expect: 'the build will fail right after calling build() with the mocked
		// unusual exception'
		this.thrown.expect(Matchers.isA(ClosedFileSystemException.class));
		builder.build();
	}

}
  • FeignClientBuilderTests验证了safetyCheckForNewFieldsOnTheFeignClientAnnotation、forType_preinitializedBuilder、forType_allFieldsSetOnBuilder、forType_build

小结

FeignClientBuilder提供了forType静态方法用于创建Builder;Builder的构造器创建了FeignClientFactoryBean,其build方法使用FeignClientFactoryBean的getTarget()来创建目标feign client

感谢各位的阅读,以上就是“spring cloud中FeignClientBuilder的用法”的内容了,经过本文的学习后,相信大家对spring cloud中FeignClientBuilder的用法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI