Spring 에서 Ordered 인터페이스 안내
머리말
Spring 에서 Ordered 인 터 페 이 스 를 제공 합 니 다.Ordered 인 터 페 이 스 는 말 그대로 정렬 에 사용 된다.
Spring 은 전략 디자인 모델 을 대량으로 사용 하 는 프레임 워 크 로 같은 인터페이스의 실현 류 가 많다 는 것 을 의미 하 므 로 반드시 우선 순위 의 문제 가 있 을 것 이다.
그래서 Spring 은 Ordered 라 는 인 터 페 이 스 를 제공 하여 같은 인터페이스 실현 류 의 우선 순위 문 제 를 처리 했다.
2.Ordered 인터페이스 소개
우선,Ordered 인터페이스의 정 의 를 살 펴 보 겠 습 니 다.
package org.springframework.core;
public abstract interface Ordered
{
public static final int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
public static final int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
public abstract int getOrder();
}
단 한 가지 방법:getOrder(); 2 개 변수:최고급(수치 최소)과 최저(수치 최대).
Order Comparator 클래스:Comparator 의 비교 기 를 실현 합 니 다.
3 개의 정적 정렬 방법 을 제공 합 니 다:sort(List>list),sort(Object[]array),sortIfNecessary(Object value).Order Comparator 에 따라 배열 과 집합 을 정렬 합 니 다.
sortIfNecessary 방법 내부 에서 value 매개 변수 가 Object[]인지 List 유형 인지 판단 한 다음 Object[]매개 변수의 sort 방법 과 List 매개 변수의 sort 방법 으로 정렬 합 니 다.
이 비교 기의 compare 방법 을 살 펴 보 자.
public int compare(Object o1, Object o2)
{
return doCompare(o1, o2, null);
}
private int doCompare(Object o1, Object o2, OrderSourceProvider sourceProvider) {
boolean p1 = o1 instanceof PriorityOrdered;
boolean p2 = o2 instanceof PriorityOrdered;
if ((p1) && (!p2)) {
return -1;
}
if ((p2) && (!p1)) {
return 1;
}
int i1 = getOrder(o1, sourceProvider);
int i2 = getOrder(o2, sourceProvider);
return i1 > i2 ? 1 : i1 < i2 ? -1 : 0;
}
private int getOrder(Object obj, OrderSourceProvider sourceProvider)
{
Integer order = null;
if (sourceProvider != null) {
Object orderSource = sourceProvider.getOrderSource(obj);
if ((orderSource != null) && (orderSource.getClass().isArray())) {
Object[] sources = ObjectUtils.toObjectArray(orderSource);
for (Object source : sources) {
order = findOrder(source);
if (order != null) {
break;
}
}
}
else {
order = findOrder(orderSource);
}
}
return order != null ? order.intValue() : getOrder(obj);
}
protected int getOrder(Object obj)
{
Integer order = findOrder(obj);
return order != null ? order.intValue() : Integer.MAX_VALUE;
}
Priority Ordered 는 Ordered 인 터 페 이 스 를 계승 하 는 인터페이스 로 방법 이 정의 되 지 않 았 습 니 다.
package org.springframework.core;
public abstract interface PriorityOrdered
extends Ordered
{}
이 코드 의 논리:
1.대상 o1 이 Ordered 인터페이스 유형 이 고 o2 가 Priority Ordered 인터페이스 유형 이 라면 o2 의 우선 순 위 는 o1 보다 높다.
2.대상 o1 이 Priority Ordered 인터페이스 유형 이 고 o2 가 Ordered 인터페이스 유형 이 라면 o1 의 우선 순 위 는 o2 보다 높다.
3.다른 경우,만약 에 둘 다 Ordered 인터페이스 유형 이거 나 둘 다 Priority Ordered 인터페이스 유형 이 라면 Ordered 인 터 페 이 스 를 호출 하 는 getOrder 방법 으로 order 값 을 얻 을 수 있 습 니 다.order 값 이 클 수록 우선 순위 가 작 습 니 다.
간단하게 요약 하면:
Order Comparator 비교 기 가 정렬 할 때 두 대상 중 한 대상 이 Priority Ordered 인 터 페 이 스 를 실현 하면 이 대상 의 우선 순위 가 더욱 높다.만약 에 두 대상 이 모두 Priority Ordered 나 Ordered 인터페이스의 실현 류 라면 Ordered 인터페이스의 getOrder 방법 을 비교 하여 order 값 을 얻 을 수 있 고 값 이 낮 을 수록 우선 순위 가 높다.
3.Ordered 인터페이스 가 Spring 에서 의 사용
SpringMVC 를 예 로 들 면 Ordered 인터페이스의 운용 을 예 로 들 수 있다.
이 설정 은*-dispatcher.xml 에서 정의 하면 SpringMVC 는 기본적으로 Request Mapping Handler Adapter 와 Request Mapping Handler Mapping 두 가지 종 류 를 주입 합 니 다.
이 부분의 내용 에 대해 서 는 건물 주의 다른 블 로 그 를 참고 하 시기 바 랍 니 다.http://bijian1013.iteye.com/blog/2310236
SpringMVC 와 기본 값 으로 Request Mapping Handler Adapter 와 Request Mapping Handler Mapping 두 종 류 를 주입 한 이상 이 두 종 류 를 다시 설정 할 수 있 습 니까?답 은 당연히 가능 하 다.
RequestMappingHandlerMapping:
RequestMappingHandlerAdapter:
text/plain;charset=UTF-8
우리 가 annotation-driven 과 이 두 개의 bean 을 설 정 했 을 때.Spring 용기 에는 Request Mapping Handler Adapter 2 개 와 Request Mapping Handler Mapping 2 개가 있다.
Dispatcher Servlet 내부 에는 Handler Mapping(Request Mapping Handler Mapping 은 그 실현 클래스)집합 과 Handler Adapter(Request Mapping Handler Adapter 는 그 실현 클래스)집합 이 있다.
private List handlerMappings;
private List handlerAdapters;
우 리 는 이 두 집합의 초기 화 코드 를 봅 시다.
private void initHandlerMappings(ApplicationContext context)
{
this.handlerMappings = null;
if (this.detectAllHandlerMappings)
{
Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
}
else {
try {
HandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
catch (NoSuchBeanDefinitionException localNoSuchBeanDefinitionException) {}
}
private void initHandlerAdapters(ApplicationContext context)
{
this.handlerAdapters = null;
if (this.detectAllHandlerAdapters)
{
Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerAdapters = new ArrayList(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerAdapters);
}
}
else {
try {
HandlerAdapter ha = (HandlerAdapter)context.getBean("handlerAdapter", HandlerAdapter.class);
this.handlerAdapters = Collections.singletonList(ha);
}
catch (NoSuchBeanDefinitionException localNoSuchBeanDefinitionException) {}
}
if (this.handlerAdapters == null) {
this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
if (this.logger.isDebugEnabled()) {
this.logger.debug("No HandlerAdapters found in servlet '" + getServletName() + "': using default");
}
}
}
AnnotationAware Order Comparator(Order Comparator 의 하위 클래스)비교 기 를 사용 하여 정렬 한 것 이 분명 합 니 다.
다음은 annotation-driven 코드 가 설정 한 Request Mapping Handler Mapping 과 Request Mapping Handler Adapter 를 살 펴 보 겠 습 니 다.
WebMvcConfigurationSupport.java
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping()
{
RequestMappingHandlerMapping handlerMapping = createRequestMappingHandlerMapping();
handlerMapping.setOrder(0);
handlerMapping.setInterceptors(getInterceptors());
handlerMapping.setContentNegotiationManager(mvcContentNegotiationManager());
handlerMapping.setCorsConfigurations(getCorsConfigurations());
PathMatchConfigurer configurer = getPathMatchConfigurer();
if (configurer.isUseSuffixPatternMatch() != null) {
handlerMapping.setUseSuffixPatternMatch(configurer.isUseSuffixPatternMatch().booleanValue());
}
if (configurer.isUseRegisteredSuffixPatternMatch() != null) {
handlerMapping.setUseRegisteredSuffixPatternMatch(configurer.isUseRegisteredSuffixPatternMatch().booleanValue());
}
if (configurer.isUseTrailingSlashMatch() != null) {
handlerMapping.setUseTrailingSlashMatch(configurer.isUseTrailingSlashMatch().booleanValue());
}
if (configurer.getPathMatcher() != null) {
handlerMapping.setPathMatcher(configurer.getPathMatcher());
}
if (configurer.getUrlPathHelper() != null) {
handlerMapping.setUrlPathHelper(configurer.getUrlPathHelper());
}
return handlerMapping;
}
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter()
{
List argumentResolvers = new ArrayList();
addArgumentResolvers(argumentResolvers);
List returnValueHandlers = new ArrayList();
addReturnValueHandlers(returnValueHandlers);
RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
adapter.setContentNegotiationManager(mvcContentNegotiationManager());
adapter.setMessageConverters(getMessageConverters());
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer());
adapter.setCustomArgumentResolvers(argumentResolvers);
adapter.setCustomReturnValueHandlers(returnValueHandlers);
if (jackson2Present) {
List requestBodyAdvices = new ArrayList();
requestBodyAdvices.add(new JsonViewRequestBodyAdvice());
adapter.setRequestBodyAdvice(requestBodyAdvices);
List> responseBodyAdvices = new ArrayList();
responseBodyAdvices.add(new JsonViewResponseBodyAdvice());
adapter.setResponseBodyAdvice(responseBodyAdvices);
}
AsyncSupportConfigurer configurer = new AsyncSupportConfigurer();
configureAsyncSupport(configurer);
if (configurer.getTaskExecutor() != null) {
adapter.setTaskExecutor(configurer.getTaskExecutor());
}
if (configurer.getTimeout() != null) {
adapter.setAsyncRequestTimeout(configurer.getTimeout().longValue());
}
adapter.setCallableInterceptors(configurer.getCallableInterceptors());
adapter.setDeferredResultInterceptors(configurer.getDeferredResultInterceptors());
return adapter;
}
RequestMappingHandlerMapping 은 기본적으로 order 속성 을 0 으로 설정 하고 RequestMappingHandlerAdapter 는 order 속성 을 설정 하지 않 습 니 다.
Request Mapping Handler Mapping 과 Request Mapping Handler Adapter 코드 에 들 어가 서 그들의 order 속성 이 어떻게 정의 되 는 지 보 겠 습 니 다.
public abstract class AbstractHandlerMethodAdapter
extends WebContentGenerator
implements HandlerAdapter, Ordered
{
private int order = Integer.MAX_VALUE;
Abstract Handler MethodAdapter 는 Request Mapping Handler Adapter 의 부류 입 니 다.
public abstract class AbstractHandlerMapping
extends WebApplicationObjectSupport
implements HandlerMapping, Ordered
{
private int order = Integer.MAX_VALUE;
Abstract Handler Mapping 은 Request Mapping Handler Mapping 의 부류 입 니 다.
Request Mapping Handler Mapping 과 Request Mapping Handler Adapter 가 order 속성 을 설정 하지 않 았 을 때 order 속성의 기본 값 은 Integer.MAX 입 니 다.VALUE,즉 우선 순위 가 가장 낮다.
PS:
설정 되 어 있 고 사용자 정의 Request Mapping HandlerAdapter 가 설정 되 어 있 으 며 Request Mapping HandlerAdapter 의 order 값 이 설정 되 어 있 지 않 으 면 이 두 Request Mapping HandlerAdapter 의 order 값 은 모두 Integer.MAX 입 니 다.VALUE。그럼 누가 우선 순위 가 높 나 요?
정 답:누가 먼저 정 의 했 는 지,누가 우선 순위 가 높 은 지.사용자 정의 Request Mapping HandlerAdapter 설정 전에 설정 한 Request Mapping HandlerAdapter 우선 순위 가 높 고,반대로 사용자 정의 Request Mapping HandlerAdapter 우선 순위 가 높 습 니 다.
설정 하면 사용자 정의 Request Mapping Handler Mapping 을 설정 하고 Request Mapping Handler Mapping 의 order 값 을 설정 하지 않 았 습 니 다.그러면 설 정 된 Request Mapping Handler Mapping 의 우선 순위 가 높 습 니 다.내부 에 Request Mapping Handler Mapping 의 order,즉 0 이 설정 되 어 있 기 때 문 입 니 다.
여러 보기 해석 기 에서 도 Ordered 인터페이스 에 사용 되 었 습 니 다.다음 과 같다.
DispatcherServlet.java
private void initViewResolvers(ApplicationContext context)
{
this.viewResolvers = null;
if (this.detectAllViewResolvers)
{
Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
if (!matchingBeans.isEmpty()) {
this.viewResolvers = new ArrayList(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.viewResolvers);
}
}
else {
try {
ViewResolver vr = (ViewResolver)context.getBean("viewResolver", ViewResolver.class);
this.viewResolvers = Collections.singletonList(vr);
}
catch (NoSuchBeanDefinitionException localNoSuchBeanDefinitionException) {}
}
if (this.viewResolvers == null) {
this.viewResolvers = getDefaultStrategies(context, ViewResolver.class);
if (this.logger.isDebugEnabled()) {
this.logger.debug("No ViewResolvers found in servlet '" + getServletName() + "': using default");
}
}
}
총화
Spring 에서 Ordered 인터페이스의 의 미 를 이해 하고 실천 에서 이 인터페이스의 활용 을 분석 했다.
이 Ordered 인터페이스 도 건물 주가 SpringMVC 에 여러 개의 보기 해석 기 를 설정 하 는 것 을 연 구 했 을 때 발 견 된 것 이다.예전 에는 별로 주의 하지 않 았 는데 사용자 정의 설정 의 RequestMappingHandlerAdapter 우선 순위 가 높 고 설정 의 RequestMappingHandlerAdapter 를 덮어 쓸 것 이 라 고 생각 했다.이 제 는 우선 순위 의 문 제 를 알 게 되 었 다.
글 의 출처:http://www.cnblogs.com/fangjian0423/p/spring-Ordered-interface.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.