DispatcherServiceletからカスタムアクセス処理

4633 ワード

DispatcherServiceletからカスタムアクセス処理
DispatcherServiceletはspringMvc処理要求の核心論理であり、処理の流れを簡単に説明するには、まずweb.xmlでこのサーブレットのサービスパスを構成します.デフォルトは/*すべてのパスです.これにより、webリクエストはサーブレットコンテナからDispatcherサーブレットに制御権フローを転送し、Dispatcherサーブレットのコアメソッドを見てみましょう.
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
	//...      ,          doDispatch
	try {
		doDispatch(request, response);
	}
	//...      
}

引き続きdoDispatchを見てみましょう.
//      ,       ,     handler
mappedHandler = getHandler(processedRequest);
//  handler        
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());


もう一度見てみましょう.
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
	//  handlerMappings      
	if (this.handlerMappings != null) {
		for (HandlerMapping mapping : this.handlerMappings) {
			HandlerExecutionChain handler = mapping.getHandler(request);
			if (handler != null) {
				return handler;
			}
		}
	}
	return null;
}

handlerアダプタの種類をもう一度見てみましょう.
HandlerAdapter (org.springframework.web.servlet)
	HttpRequestHandlerAdapter (org.springframework.web.servlet.mvc)
	SimpleServletHandlerAdapter (org.springframework.web.servlet.handler)
	AbstractHandlerMethodAdapter (org.springframework.web.servlet.mvc.method)
		RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
	SimpleControllerHandlerAdapter (org.springframework.web.servlet.mvc)

HttpRequestHandler,Servicelet,Controller,@RequestMapping
次に、HandlerMappingとHandlerAdapterをspringに構成する方法を見てみましょう.
private void initHandlerMappings(ApplicationContext context) {
	this.handlerMappings = null;

	if (this.detectAllHandlerMappings) {
		//            HandlerMapping  
		Map matchingBeans =
				BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
		if (!matchingBeans.isEmpty()) {
			this.handlerMappings = new ArrayList<>(matchingBeans.values());
			// We keep HandlerMappings in sorted order.
			AnnotationAwareOrderComparator.sort(this.handlerMappings);
		}
	}
	else {
		try {
			HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
			//      
			this.handlerMappings = Collections.singletonList(hm);
		}
		catch (NoSuchBeanDefinitionException ex) {
			// Ignore, we'll add a default HandlerMapping later.
		}
	}
	//      
}

HandlerAdapterの初期化は、上記と同様です.
private void initHandlerAdapters(ApplicationContext context) {
	this.handlerAdapters = null;

	if (this.detectAllHandlerAdapters) {
		// Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
		Map matchingBeans =
				BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
		if (!matchingBeans.isEmpty()) {
			this.handlerAdapters = new ArrayList<>(matchingBeans.values());
			// We keep HandlerAdapters in sorted order.
			AnnotationAwareOrderComparator.sort(this.handlerAdapters);
		}
	}
	else {
		try {
			HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
			this.handlerAdapters = Collections.singletonList(ha);
		}
		catch (NoSuchBeanDefinitionException ex) {
			// Ignore, we'll add a default HandlerAdapter later.
		}
	}

	//      
}

実践してみましょう:クラスをカスタマイズします.
public class MyController implements HttpRequestHandler {

    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setHeader(HttpHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN_VALUE);
        ServletOutputStream os = response.getOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(os);
        bos.write("my controller...".getBytes());
        bos.flush();
    }

}

アダプタの構成:
@Configuration
public class MyMappingConfig {

    @Bean
    public HandlerMapping handlerMapping(){
        SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
        Map map = new HashMap<>();
        map.put("/test/test.html", new MyController());
        mapping.setUrlMap(map);
        mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 100);
        return mapping;
    }

}


結果:
my controller...

このようにjarパッケージに自動的に注入することで、自分のサービスを暴露することができる.例えばspringのactuator(もちろん、ここよりずっと複雑です)