001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.servlet.view; 018 019import java.util.Locale; 020 021import org.springframework.beans.BeansException; 022import org.springframework.context.ApplicationContext; 023import org.springframework.core.Ordered; 024import org.springframework.lang.Nullable; 025import org.springframework.web.context.support.WebApplicationObjectSupport; 026import org.springframework.web.servlet.View; 027import org.springframework.web.servlet.ViewResolver; 028 029/** 030 * A simple implementation of {@link org.springframework.web.servlet.ViewResolver} 031 * that interprets a view name as a bean name in the current application context, 032 * i.e. typically in the XML file of the executing {@code DispatcherServlet}. 033 * 034 * <p>This resolver can be handy for small applications, keeping all definitions 035 * ranging from controllers to views in the same place. For larger applications, 036 * {@link XmlViewResolver} will be the better choice, as it separates the XML 037 * view bean definitions into a dedicated views file. 038 * 039 * <p>Note: Neither this {@code ViewResolver} nor {@link XmlViewResolver} supports 040 * internationalization. Consider {@link ResourceBundleViewResolver} if you need 041 * to apply different view resources per locale. 042 * 043 * <p>Note: This {@code ViewResolver} implements the {@link Ordered} interface 044 * in order to allow for flexible participation in {@code ViewResolver} chaining. 045 * For example, some special views could be defined via this {@code ViewResolver} 046 * (giving it 0 as "order" value), while all remaining views could be resolved by 047 * a {@link UrlBasedViewResolver}. 048 * 049 * @author Juergen Hoeller 050 * @since 18.06.2003 051 * @see XmlViewResolver 052 * @see ResourceBundleViewResolver 053 * @see UrlBasedViewResolver 054 */ 055public class BeanNameViewResolver extends WebApplicationObjectSupport implements ViewResolver, Ordered { 056 057 private int order = Ordered.LOWEST_PRECEDENCE; // default: same as non-Ordered 058 059 060 /** 061 * Specify the order value for this ViewResolver bean. 062 * <p>The default value is {@code Ordered.LOWEST_PRECEDENCE}, meaning non-ordered. 063 * @see org.springframework.core.Ordered#getOrder() 064 */ 065 public void setOrder(int order) { 066 this.order = order; 067 } 068 069 @Override 070 public int getOrder() { 071 return this.order; 072 } 073 074 075 @Override 076 @Nullable 077 public View resolveViewName(String viewName, Locale locale) throws BeansException { 078 ApplicationContext context = obtainApplicationContext(); 079 if (!context.containsBean(viewName)) { 080 // Allow for ViewResolver chaining... 081 return null; 082 } 083 if (!context.isTypeMatch(viewName, View.class)) { 084 if (logger.isDebugEnabled()) { 085 logger.debug("Found bean named '" + viewName + "' but it does not implement View"); 086 } 087 // Since we're looking into the general ApplicationContext here, 088 // let's accept this as a non-match and allow for chaining as well... 089 return null; 090 } 091 return context.getBean(viewName, View.class); 092 } 093 094}