聊聊springboot2的MappingsEndpoint

本文主要研究下springboot2的MappingsEndpoint

MappingsEndpointAutoConfiguration

spring-boot-actuator-autoconfigure-2.0.1.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfiguration.java

@ManagementContextConfiguration
public class MappingsEndpointAutoConfiguration {

	@Bean
	@ConditionalOnEnabledEndpoint
	public MappingsEndpoint mappingsEndpoint(ApplicationContext applicationContext,
			ObjectProvider<Collection<MappingDescriptionProvider>> descriptionProviders) {
		return new MappingsEndpoint(
				descriptionProviders.getIfAvailable(Collections::emptyList),
				applicationContext);
	}

	@Configuration
	@ConditionalOnWebApplication(type = Type.SERVLET)
	static class ServletWebConfiguration {

		@Bean
		ServletsMappingDescriptionProvider servletMappingDescriptionProvider() {
			return new ServletsMappingDescriptionProvider();
		}

		@Bean
		FiltersMappingDescriptionProvider filterMappingDescriptionProvider() {
			return new FiltersMappingDescriptionProvider();
		}

		@Configuration
		@ConditionalOnClass(DispatcherServlet.class)
		@ConditionalOnBean(DispatcherServlet.class)
		static class SpringMvcConfiguration {

			@Bean
			DispatcherServletsMappingDescriptionProvider dispatcherServletMappingDescriptionProvider() {
				return new DispatcherServletsMappingDescriptionProvider();
			}

		}

	}

	@Configuration
	@ConditionalOnWebApplication(type = Type.REACTIVE)
	@ConditionalOnClass(DispatcherHandler.class)
	@ConditionalOnBean(DispatcherHandler.class)
	static class ReactiveWebConfiguration {

		@Bean
		public DispatcherHandlersMappingDescriptionProvider dispatcherHandlerMappingDescriptionProvider(
				ApplicationContext applicationContext) {
			return new DispatcherHandlersMappingDescriptionProvider();
		}

	}

}
复制代码

这里使用descriptionProviders创建mappingsEndpoint,然后根据是servlet或reactive的方式来创建不同的MappingDescriptionProvider,servlet创建的是ServletsMappingDescriptionProvider,FiltersMappingDescriptionProvider,DispatcherServletsMappingDescriptionProvider,reactive创建的是DispatcherHandlersMappingDescriptionProvider

MappingsEndpoint

spring-boot-actuator-2.0.1.RELEASE-sources.jar!/org/springframework/boot/actuate/web/mappings/MappingsEndpoint.java

@Endpoint(id = "mappings")
public class MappingsEndpoint {

	private final Collection<MappingDescriptionProvider> descriptionProviders;

	private final ApplicationContext context;

	public MappingsEndpoint(Collection<MappingDescriptionProvider> descriptionProviders,
			ApplicationContext context) {
		this.descriptionProviders = descriptionProviders;
		this.context = context;
	}

	@ReadOperation
	public ApplicationMappings mappings() {
		ApplicationContext target = this.context;
		Map<String, ContextMappings> contextMappings = new HashMap<>();
		while (target != null) {
			contextMappings.put(target.getId(), mappingsForContext(target));
			target = target.getParent();
		}
		return new ApplicationMappings(contextMappings);
	}

	private ContextMappings mappingsForContext(ApplicationContext applicationContext) {
		Map<String, Object> mappings = new HashMap<>();
		this.descriptionProviders
				.forEach((provider) -> mappings.put(provider.getMappingName(),
						provider.describeMappings(applicationContext)));
		return new ContextMappings(mappings, applicationContext.getParent() == null ? null
				: applicationContext.getId());
	}
	//......
}
复制代码

这里根据descriptionProviders创建ContextMappings

servlet方式

ServletsMappingDescriptionProvider

spring-boot-actuator-2.0.1.RELEASE-sources.jar!/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProvider.java

public class ServletsMappingDescriptionProvider implements MappingDescriptionProvider {

	@Override
	public List<ServletRegistrationMappingDescription> describeMappings(
			ApplicationContext context) {
		if (!(context instanceof WebApplicationContext)) {
			return Collections.emptyList();
		}
		return ((WebApplicationContext) context).getServletContext()
				.getServletRegistrations().values().stream()
				.map(ServletRegistrationMappingDescription::new)
				.collect(Collectors.toList());
	}

	@Override
	public String getMappingName() {
		return "servlets";
	}

}
复制代码

这里从servletContext中获取ServletRegistrations,再获取ServletRegistrationMappingDescription

FiltersMappingDescriptionProvider

spring-boot-actuator-2.0.1.RELEASE-sources.jar!/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProvider.java

public class FiltersMappingDescriptionProvider implements MappingDescriptionProvider {

	@Override
	public List<FilterRegistrationMappingDescription> describeMappings(
			ApplicationContext context) {
		if (!(context instanceof WebApplicationContext)) {
			return Collections.emptyList();
		}
		return ((WebApplicationContext) context).getServletContext()
				.getFilterRegistrations().values().stream()
				.map(FilterRegistrationMappingDescription::new)
				.collect(Collectors.toList());
	}

	@Override
	public String getMappingName() {
		return "servletFilters";
	}

}
复制代码

这里从servletContext中获取FilterRegistrations,再获取FilterRegistrationMappingDescription

DispatcherServletsMappingDescriptionProvider

spring-boot-actuator-2.0.1.RELEASE-sources.jar!/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProvider.java

public class DispatcherServletsMappingDescriptionProvider
		implements MappingDescriptionProvider {

	private static final List<HandlerMappingDescriptionProvider<? extends HandlerMapping>> descriptionProviders;

	static {
		List<HandlerMappingDescriptionProvider<? extends HandlerMapping>> providers = new ArrayList<>();
		providers.add(new RequestMappingInfoHandlerMappingDescriptionProvider());
		providers.add(new UrlHandlerMappingDescriptionProvider());
		if (ClassUtils.isPresent(
				"org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping",
				null)) {
			providers.add(new DelegatingHandlerMappingDescriptionProvider(
					new ArrayList<>(providers)));
		}
		descriptionProviders = Collections.unmodifiableList(providers);
	}

	@Override
	public String getMappingName() {
		return "dispatcherServlets";
	}

	@Override
	public Map<String, List<DispatcherServletMappingDescription>> describeMappings(
			ApplicationContext context) {
		if (context instanceof WebApplicationContext) {
			return describeMappings((WebApplicationContext) context);
		}
		return Collections.emptyMap();
	}

	private Map<String, List<DispatcherServletMappingDescription>> describeMappings(
			WebApplicationContext context) {
		Map<String, List<DispatcherServletMappingDescription>> mappings = new HashMap<>();
		context.getBeansOfType(DispatcherServlet.class)
				.forEach((name, dispatcherServlet) -> mappings.put(name,
						describeMappings(new DispatcherServletHandlerMappings(name,
								dispatcherServlet, context))));
		return mappings;
	}

	private List<DispatcherServletMappingDescription> describeMappings(
			DispatcherServletHandlerMappings mappings) {
		return mappings.getHandlerMappings().stream().flatMap(this::describe)
				.collect(Collectors.toList());
	}

	private <T extends HandlerMapping> Stream<DispatcherServletMappingDescription> describe(
			T handlerMapping) {
		return describe(handlerMapping, descriptionProviders).stream();
	}

	@SuppressWarnings("unchecked")
	private static <T extends HandlerMapping> List<DispatcherServletMappingDescription> describe(
			T handlerMapping,
			List<HandlerMappingDescriptionProvider<?>> descriptionProviders) {
		for (HandlerMappingDescriptionProvider<?> descriptionProvider : descriptionProviders) {
			if (descriptionProvider.getMappingClass().isInstance(handlerMapping)) {
				return ((HandlerMappingDescriptionProvider<T>) descriptionProvider)
						.describe(handlerMapping);
			}
		}
		return Collections.emptyList();
	}
	//......
}
复制代码

这里主要从DelegatingHandlerMappingDescriptionProvider、RequestMappingInfoHandlerMappingDescriptionProvider、UrlHandlerMappingDescriptionProvider获取DispatcherServletMappingDescription

reactive方式

DispatcherHandlersMappingDescriptionProvider

spring-boot-actuator-2.0.1.RELEASE-sources.jar!/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProvider.java

public class DispatcherHandlersMappingDescriptionProvider
		implements MappingDescriptionProvider {

	private static final List<HandlerMappingDescriptionProvider<? extends HandlerMapping>> descriptionProviders = Arrays
			.asList(new RequestMappingInfoHandlerMappingDescriptionProvider(),
					new UrlHandlerMappingDescriptionProvider(),
					new RouterFunctionMappingDescriptionProvider());

	@Override
	public String getMappingName() {
		return "dispatcherHandlers";
	}

	@Override
	public Map<String, List<DispatcherHandlerMappingDescription>> describeMappings(
			ApplicationContext context) {
		Map<String, List<DispatcherHandlerMappingDescription>> mappings = new HashMap<>();
		context.getBeansOfType(DispatcherHandler.class).forEach(
				(name, handler) -> mappings.put(name, describeMappings(handler)));
		return mappings;
	}

	private List<DispatcherHandlerMappingDescription> describeMappings(
			DispatcherHandler dispatcherHandler) {
		return dispatcherHandler.getHandlerMappings().stream().flatMap(this::describe)
				.collect(Collectors.toList());
	}

	@SuppressWarnings("unchecked")
	private <T extends HandlerMapping> Stream<DispatcherHandlerMappingDescription> describe(
			T handlerMapping) {
		for (HandlerMappingDescriptionProvider<?> descriptionProvider : descriptionProviders) {
			if (descriptionProvider.getMappingClass().isInstance(handlerMapping)) {
				return ((HandlerMappingDescriptionProvider<T>) descriptionProvider)
						.describe(handlerMapping).stream();

			}
		}
		return Stream.empty();
	}
	//......
}
复制代码

与servlet获取DispatcherServletsMappingDescriptionProvider不同,reactive获取的是DispatcherHandlersMappingDescriptionProvider 主要从RequestMappingInfoHandlerMappingDescriptionProvider、RouterFunctionMappingDescriptionProvider、UrlHandlerMappingDescriptionProvider这三个来获取HandlerMappingDescriptionProvider

小结

springboot2的MappingsEndpoint通过provider根据servlet及reactive分别进行各自的mappings获取,servlet主要分为ServletsMappingDescriptionProvider、FiltersMappingDescriptionProvider、DispatcherServletsMappingDescriptionProvider,而reactive主要分为DispatcherHandlersMappingDescriptionProvider

doc

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值