spring MVC 작업 체제 와 디자인 모델 - 독후 소결 (2)

7898 단어 spring
오늘 은 주로 며칠 전 저녁 에 Control 디자인 을 봤 습 니 다.
제어 설계
Spring MVC 의 Control 은 주로 Handler Mapping (interface) 과 Handler Adapter (interface) 두 구성 요소 가 제공 합 니 다.
  • org.springframework.web.servlet.HandlerMapping
  • org.springframework.web.servlet.HandlerAdapter

  • HandlerMapping: 사용자 의 URL 과 대응 하 는 처리 클래스 를 매 핑 하 는 것 을 담당 합 니 다. HandlerMapping 은 이 URL 과 응용 처리 클래스 가 어떻게 매 핑 되 는 지 규정 하지 않 았 습 니 다. HandlerMapping 인터페이스 에 서 는 하나의 URL 에 따라 HandlerExceptionChain 이 대표 하 는 처리 체인 을 되 돌려 야 한다 고 만 정 의 했 습 니 다.우 리 는 이 처리 체인 에 임의의 HandlerAdapter 인 스 턴 스 를 추가 하여 이 URL 에 대응 하 는 요 구 를 처리 할 수 있 습 니 다. 이 디자인 방향 은 Servlet 규범 중의 Filter 처리 와 유사 합 니 다.
    사악 한 분할 선
    HandlerMapping 초기 화
    Spring MVC 자체 도 HandlerMapping 의 실현 을 많이 제 공 했 습 니 다. 기본적으로 BeanNameUrl HandlerMapping 을 사용 하고 Bean 의 name 속성 에 따라 URL 에 매 핑 할 수 있 습 니 다.
    /**
    	 * Return a handler and any interceptors for this request. The choice may be made
    	 * on request URL, session state, or any factor the implementing class chooses.
    	 * <p>The returned HandlerExecutionChain contains a handler Object, rather than
    	 * even a tag interface, so that handlers are not constrained in any way.
    	 * For example, a HandlerAdapter could be written to allow another framework's
    	 * handler objects to be used.
    	 * <p>Returns <code>null</code> if no match was found. This is not an error.
    	 * The DispatcherServlet will query all registered HandlerMapping beans to find
    	 * a match, and only decide there is an error if none can find a handler.
    	 * @param request current HTTP request
    	 * @return a HandlerExecutionChain instance containing handler object and
    	 * any interceptors, or <code>null</code> if no mapping found
    	 * @throws Exception if there is an internal error
    	 */
    	HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

    Handler Mapping 에 대해 서 는 URL 과 처리 류 의 맵 관 계 를 관리 하 는 데 도움 을 줄 수 있 습 니 다. 쉽게 말 하면 하나 이상 의 URL 을 하나 이상 의 spring Bean 에 투사 하 는 데 도움 을 줄 수 있 습 니 다.
    spring MVC 가 우리 가 정의 하 는 bean 에 요청 한 URL 을 어떻게 비 추 는 지 정리 합 니 다.
        Handler Mapping 이 어떻게 초기 화 되 었 는 지spring MVC 는 Handler Mapping 의 추상 적 인 추상 류 Abstract Handler Mapping 을 제공 합 니 다.
    public class BeanNameUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping {
    
    	/**
    	 * Checks name and aliases of the given bean for URLs, starting with "/".
    	 */
    	@Override
    	protected String[] determineUrlsForHandler(String beanName) {
    		List<String> urls = new ArrayList<String>();
    		if (beanName.startsWith("/")) {
    			urls.add(beanName);
    		}
    		String[] aliases = getApplicationContext().getAliases(beanName);
    		for (String alias : aliases) {
    			if (alias.startsWith("/")) {
    				urls.add(alias);
    			}
    		}
    		return StringUtils.toStringArray(urls);
    	}
    
    }
    Handler Mapping 에 setOrder 를 설정 하 는 방법 으로 우선 순 위 를 높이 고 initapplicationContext 를 덮어 쓰 는 방법 으로 초기 화 할 수 있 습 니 다.
    public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
    		implements HandlerMapping, Ordered {
    }

    Simple Url Handler Mapping 클래스 를 어떻게 초기 화 합 니까?
  • 먼저 ApplicationObject Support 의 setApplicationContext () 방법 을 호출 합 니 다.
  • 	@Override
    	protected void initApplicationContext() throws BeansException {
    		extendInterceptors(this.interceptors);
    		detectMappedInterceptors(this.mappedInterceptors);
    		initInterceptors();
    	}
    
  • SimpleUrl HandlerMapping 의 initapplicationContext () 방법
  • 을 호출 합 니 다.
    public final void setApplicationContext(ApplicationContext context) throws BeansException {
    		if (context == null && !isContextRequired()) {
    			// Reset internal context state.
    			this.applicationContext = null;
    			this.messageSourceAccessor = null;
    		}
    		else if (this.applicationContext == null) {
    			// Initialize with passed-in context.
    			if (!requiredContextClass().isInstance(context)) {
    				throw new ApplicationContextException(
    						"Invalid application context: needs to be of type [" + requiredContextClass().getName() + "]");
    			}
    			this.applicationContext = context;
    			this.messageSourceAccessor = new MessageSourceAccessor(context);
    			initApplicationContext(context);
    		}
    		else {
    			// Ignore reinitialization if same context passed in.
    			if (this.applicationContext != context) {
    				throw new ApplicationContextException(
    						"Cannot reinitialize with different application context: current one is [" +
    						this.applicationContext + "], passed-in one is [" + context + "]");
    			}
    		}
    	}
  • 슈퍼. initapplicationContext () 를 호출 하고 AbstractHandler Mapping 의 initapplicationContext () 방법
  • 을 호출 했다.
    /**
    	 * Calls the {@link #registerHandlers} method in addition to the
    	 * superclass's initialization.
    	 */
    	@Override
    	public void initApplicationContext() throws BeansException {
    		super.initApplicationContext();
    		registerHandlers(this.urlMap);
    	}
    initInterceptors () 초기 화 방법: SimpleUrl Handler Mapping 에서 정의 하 는 interceptors 를 handler Interceptor 대상 으로 포장 하여 adapted Interceptors 배열 에 저장 합 니 다.
  • SimpleUrlHandlerMapping 은 registerHandlers (this. url Map) 방법 을 계속 실행 합 니 다.

  • 방법 registerHandlers 에서 AbstractUrl Handler Mapping 의 registerHandler (url, handler) 방법 을 호출 하 였 습 니 다.
    방법 registerHandler (url, handler) 에 서 는 Simple Url Handler Mapping 에서 정의 하 는 mappings 를 handlerMap 집합 에 등록 합 니 다.
    /**
    	 * Initializes the interceptors.
    	 * @see #extendInterceptors(java.util.List)
    	 * @see #initInterceptors()
    	 */
    	@Override
    	protected void initApplicationContext() throws BeansException {
    		extendInterceptors(this.interceptors);
    		detectMappedInterceptors(this.mappedInterceptors);
    		initInterceptors();
    	}
    registerHandler 방법 에서;
    사악 한 분할 선
    소결: Handler Mapping 초기 화 작업 이 완 료 된 두 가지 가장 중요 한 작업 은:
  • URL 과 Handler 의 대응 관 계 를 Handler Mapping 집합 에 저장 하고 모든 interceptors 대상 을 adapted Interceptors 배열 에 저장 하 며 요청 이 올 때 모든 adapted Intercoptors 배열 의 interceptor 대상 을 실행 합 니 다.
  • 모든 interceptor 는 Handler Interceptor 인 터 페 이 스 를 실현 해 야 합 니 다.

  • 사악 한 분할 선
    HandlerAdapter 초기 화
    Handler Mapping 은 URL 과 Handler 의 매 핑 관 계 를 완성 할 수 있 습 니 다. 그러면 Handler Adapter 는 각종 handler 를 사용자 정의 하 는 데 도움 을 줄 수 있 습 니 다.SpringMVC 는 먼저 특별한 URL 을 Handler 에 대응 하 는 데 도움 을 주기 때문에 이 Handler 는 반드시 특정한 규칙 에 부합 해 야 한다. 가장 흔히 볼 수 있 는 방법 은 우리 의 모든 handler 가 특정한 인 터 페 이 스 를 계승 한 다음 에 SpringMVC 는 이 인터페이스 에서 정 의 된 특성 방법 을 자 연 스 럽 게 호출 하 는 것 이다.
    spring MVC 에 대해 세 가지 전형 적 인 handler Adapter 실현 류 를 제공 합 니 다.
  • Simple ServletHandlerAdapter: Servlet 인 터 페 이 스 를 직접 계승 할 수 있 습 니 다.
  • Simple Controller Handler Adapter: Controller 인 터 페 이 스 를 계승 할 수 있 습 니 다.
  • Simple RequestHandler Adapter: HttpRequuset Handler 인 터 페 이 스 를 계승 할 수 있 습 니 다.

  • handlerAdapter 초기 화 에 대해 서 는 특별한 점 이 없습니다. handlerAdapter 대상 을 간단하게 만 들 고 이 대상 을 Dispatcher Servlet 의 HandlerAdapters 집합 에 저장 합 니 다.Spring MVC 가 어떤 URL 을 한 Handler 에 대응 할 때 handlerAdapters 집합 에서 handlerAdapter 대상 supports 라 는 Handler 를 조회 하면 handlerAdapter 대상 이 되 돌아 오고 이 handlerAdapter 인 터 페 이 스 를 호출 하 는 방법 을 사용 합 니 다.
    사악 한 분할 선
    Control 호출 논리
    전체 Spring MVC 호출 은 Dispatcher Servlet 의 doService 방법 에서 시 작 됩 니 다. doService 방법 에 서 는 applicationContext, locale Resolver, theme Resolver 등 대상 을 request 에 추가 하여 뒤에서 사용 하기 편 합 니 다. 이 어 doDispatch 방법 을 호출 합 니 다. 이 방법 은 사용자 의 요청 을 처리 하 는 곳 입 니 다.

    좋은 웹페이지 즐겨찾기