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.method.annotation; 018 019import javax.servlet.ServletException; 020 021import org.springframework.beans.factory.annotation.Value; 022import org.springframework.beans.factory.config.ConfigurableBeanFactory; 023import org.springframework.core.MethodParameter; 024import org.springframework.lang.Nullable; 025import org.springframework.util.Assert; 026import org.springframework.web.bind.WebDataBinder; 027import org.springframework.web.context.request.NativeWebRequest; 028 029/** 030 * Resolves method arguments annotated with {@code @Value}. 031 * 032 * <p>An {@code @Value} does not have a name but gets resolved from the default 033 * value string, which may contain ${...} placeholder or Spring Expression 034 * Language #{...} expressions. 035 * 036 * <p>A {@link WebDataBinder} may be invoked to apply type conversion to 037 * resolved argument value. 038 * 039 * @author Rossen Stoyanchev 040 * @since 3.1 041 */ 042public class ExpressionValueMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver { 043 044 /** 045 * Create a new {@link ExpressionValueMethodArgumentResolver} instance. 046 * @param beanFactory a bean factory to use for resolving ${...} 047 * placeholder and #{...} SpEL expressions in default values; 048 * or {@code null} if default values are not expected to contain expressions 049 */ 050 public ExpressionValueMethodArgumentResolver(@Nullable ConfigurableBeanFactory beanFactory) { 051 super(beanFactory); 052 } 053 054 055 @Override 056 public boolean supportsParameter(MethodParameter parameter) { 057 return parameter.hasParameterAnnotation(Value.class); 058 } 059 060 @Override 061 protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) { 062 Value ann = parameter.getParameterAnnotation(Value.class); 063 Assert.state(ann != null, "No Value annotation"); 064 return new ExpressionValueNamedValueInfo(ann); 065 } 066 067 @Override 068 @Nullable 069 protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest webRequest) throws Exception { 070 // No name to resolve 071 return null; 072 } 073 074 @Override 075 protected void handleMissingValue(String name, MethodParameter parameter) throws ServletException { 076 throw new UnsupportedOperationException("@Value is never required: " + parameter.getMethod()); 077 } 078 079 080 private static final class ExpressionValueNamedValueInfo extends NamedValueInfo { 081 082 private ExpressionValueNamedValueInfo(Value annotation) { 083 super("@Value", false, annotation.value()); 084 } 085 } 086 087}