聊聊springboot2的MappingsEndpoint

本文主要研究下springboot2的MappingsEndpointhtml

MappingsEndpointAutoConfiguration

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

@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建立的是DispatcherHandlersMappingDescriptionProviderreact

MappingsEndpoint

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

@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建立ContextMappingsspring

servlet方式

ServletsMappingDescriptionProvider

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

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,再獲取ServletRegistrationMappingDescriptionmvc

FiltersMappingDescriptionProvider

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

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,再獲取FilterRegistrationMappingDescriptionide

DispatcherServletsMappingDescriptionProvider

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

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

相關文章
相關標籤/搜索