|
13 | 13 | * See the License for the specific language governing permissions and
|
14 | 14 | * limitations under the License.
|
15 | 15 | */
|
| 16 | + |
16 | 17 | package org.springframework.web.servlet.config;
|
17 | 18 |
|
| 19 | +import org.w3c.dom.Element; |
| 20 | + |
18 | 21 | import org.springframework.beans.factory.config.BeanDefinition;
|
19 |
| -import org.springframework.beans.factory.config.BeanDefinitionHolder; |
| 22 | +import org.springframework.beans.factory.config.RuntimeBeanReference; |
20 | 23 | import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
21 | 24 | import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
|
22 |
| -import org.springframework.beans.factory.support.BeanDefinitionBuilder; |
| 25 | +import org.springframework.beans.factory.support.RootBeanDefinition; |
23 | 26 | import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
24 | 27 | import org.springframework.beans.factory.xml.ParserContext;
|
25 | 28 | import org.springframework.core.convert.ConversionService;
|
|
30 | 33 | import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
31 | 34 | import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
|
32 | 35 | import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;
|
33 |
| -import org.w3c.dom.Element; |
34 | 36 |
|
35 | 37 | /**
|
36 | 38 | * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses the {@code annotation-driven} element to configure
|
|
46 | 48 | * <li>Configures the validator if specified, otherwise defaults to a fresh {@link Validator} instance created by the default {@link LocalValidatorFactoryBean} <i>if the JSR-303 API is present in the classpath.
|
47 | 49 | * </ul>
|
48 | 50 | * </ol>
|
| 51 | + * |
49 | 52 | * @author Keith Donald
|
| 53 | + * @author Juergen Hoeller |
50 | 54 | * @since 3.0
|
51 | 55 | */
|
52 |
| -public class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { |
| 56 | +class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { |
| 57 | + |
| 58 | + private static final boolean jsr303Present = ClassUtils.isPresent( |
| 59 | + "javax.validation.Validator", AnnotationDrivenBeanDefinitionParser.class.getClassLoader()); |
| 60 | + |
53 | 61 |
|
54 | 62 | public BeanDefinition parse(Element element, ParserContext parserContext) {
|
55 | 63 | Object source = parserContext.extractSource(element);
|
56 |
| - BeanDefinitionHolder handlerMappingHolder = registerDefaultAnnotationHandlerMapping(element, source, parserContext); |
57 |
| - BeanDefinitionHolder handlerAdapterHolder = registerAnnotationMethodHandlerAdapter(element, source, parserContext); |
58 |
| - |
| 64 | + |
| 65 | + RootBeanDefinition mappingDef = new RootBeanDefinition(DefaultAnnotationHandlerMapping.class); |
| 66 | + mappingDef.setSource(source); |
| 67 | + mappingDef.getPropertyValues().add("order", 0); |
| 68 | + String mappingName = parserContext.getReaderContext().registerWithGeneratedName(mappingDef); |
| 69 | + |
| 70 | + RootBeanDefinition bindingDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class); |
| 71 | + bindingDef.setSource(source); |
| 72 | + bindingDef.getPropertyValues().add("conversionService", getConversionService(element, source, parserContext)); |
| 73 | + bindingDef.getPropertyValues().add("validator", getValidator(element, source, parserContext)); |
| 74 | + |
| 75 | + RootBeanDefinition adapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class); |
| 76 | + adapterDef.setSource(source); |
| 77 | + adapterDef.getPropertyValues().add("webBindingInitializer", bindingDef); |
| 78 | + String adapterName = parserContext.getReaderContext().registerWithGeneratedName(adapterDef); |
| 79 | + |
59 | 80 | CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
|
60 | 81 | parserContext.pushContainingComponent(compDefinition);
|
61 |
| - parserContext.registerComponent(new BeanComponentDefinition(handlerMappingHolder)); |
62 |
| - parserContext.registerComponent(new BeanComponentDefinition(handlerAdapterHolder)); |
| 82 | + parserContext.registerComponent(new BeanComponentDefinition(mappingDef, mappingName)); |
| 83 | + parserContext.registerComponent(new BeanComponentDefinition(adapterDef, adapterName)); |
63 | 84 | parserContext.popAndRegisterContainingComponent();
|
64 | 85 |
|
65 | 86 | return null;
|
66 | 87 | }
|
67 | 88 |
|
68 |
| - // internal helpers |
69 |
| - |
70 |
| - private BeanDefinitionHolder registerDefaultAnnotationHandlerMapping(Element element, Object source, ParserContext context) { |
71 |
| - BeanDefinitionBuilder builder = createBeanBuilder(DefaultAnnotationHandlerMapping.class, source); |
72 |
| - builder.addPropertyValue("order", 0); |
73 |
| - return registerBeanDefinition(builder.getBeanDefinition(), context); |
74 |
| - } |
75 | 89 |
|
76 |
| - private BeanDefinitionHolder registerAnnotationMethodHandlerAdapter(Element element, Object source, ParserContext context) { |
77 |
| - BeanDefinitionBuilder builder = createBeanBuilder(AnnotationMethodHandlerAdapter.class, source); |
78 |
| - builder.addPropertyValue("webBindingInitializer", createWebBindingInitializer(element, source, context)); |
79 |
| - return registerBeanDefinition(builder.getBeanDefinition(), context); |
80 |
| - } |
81 |
| - |
82 |
| - private BeanDefinition createWebBindingInitializer(Element element, Object source, ParserContext context) { |
83 |
| - BeanDefinitionBuilder builder = createBeanBuilder(ConfigurableWebBindingInitializer.class, source); |
84 |
| - addConversionService(builder, element, source, context); |
85 |
| - addValidator(builder, element, source, context); |
86 |
| - return builder.getBeanDefinition(); |
87 |
| - } |
88 |
| - |
89 |
| - private void addConversionService(BeanDefinitionBuilder builder, Element element, Object source, ParserContext context) { |
| 90 | + private Object getConversionService(Element element, Object source, ParserContext parserContext) { |
90 | 91 | if (element.hasAttribute("conversion-service")) {
|
91 |
| - builder.addPropertyReference("conversionService", element.getAttribute("conversion-service")); |
92 |
| - } else { |
93 |
| - builder.addPropertyValue("conversionService", createDefaultConversionService(element, source, context)); |
| 92 | + return new RuntimeBeanReference(element.getAttribute("conversion-service")); |
| 93 | + } |
| 94 | + else { |
| 95 | + RootBeanDefinition conversionDef = new RootBeanDefinition(FormattingConversionServiceFactoryBean.class); |
| 96 | + conversionDef.setSource(source); |
| 97 | + String conversionName = parserContext.getReaderContext().registerWithGeneratedName(conversionDef); |
| 98 | + return new RuntimeBeanReference(conversionName); |
94 | 99 | }
|
95 | 100 | }
|
96 | 101 |
|
97 |
| - private void addValidator(BeanDefinitionBuilder builder, Element element, Object source, ParserContext context) { |
| 102 | + private Object getValidator(Element element, Object source, ParserContext parserContext) { |
98 | 103 | if (element.hasAttribute("validator")) {
|
99 |
| - builder.addPropertyReference("validator", element.getAttribute("validator")); |
100 |
| - } else { |
101 |
| - if (ClassUtils.isPresent("javax.validation.Validator", AnnotationDrivenBeanDefinitionParser.class.getClassLoader())) { |
102 |
| - builder.addPropertyValue("validator", createDefaultValidator(element, source, context)); |
103 |
| - } |
| 104 | + return new RuntimeBeanReference(element.getAttribute("validator")); |
| 105 | + } |
| 106 | + else if (jsr303Present) { |
| 107 | + RootBeanDefinition validatorDef = new RootBeanDefinition(LocalValidatorFactoryBean.class); |
| 108 | + validatorDef.setSource(source); |
| 109 | + String validatorName = parserContext.getReaderContext().registerWithGeneratedName(validatorDef); |
| 110 | + return new RuntimeBeanReference(validatorName); |
| 111 | + } |
| 112 | + else { |
| 113 | + return null; |
104 | 114 | }
|
105 |
| - } |
106 |
| - |
107 |
| - private BeanDefinition createDefaultConversionService(Element element, Object source, ParserContext context) { |
108 |
| - BeanDefinitionBuilder builder = createBeanBuilder(FormattingConversionServiceFactoryBean.class, source); |
109 |
| - return builder.getBeanDefinition(); |
110 |
| - } |
111 |
| - |
112 |
| - private BeanDefinition createDefaultValidator(Element element, Object source, ParserContext context) { |
113 |
| - BeanDefinitionBuilder builder = createBeanBuilder(LocalValidatorFactoryBean.class, source); |
114 |
| - return builder.getBeanDefinition(); |
115 |
| - } |
116 |
| - |
117 |
| - private BeanDefinitionHolder registerBeanDefinition(BeanDefinition definition, ParserContext context) { |
118 |
| - String beanName = context.getReaderContext().generateBeanName(definition); |
119 |
| - context.getRegistry().registerBeanDefinition(beanName, definition); |
120 |
| - return new BeanDefinitionHolder(definition, beanName); |
121 |
| - } |
122 |
| - |
123 |
| - private BeanDefinitionBuilder createBeanBuilder(Class<?> clazz, Object source) { |
124 |
| - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz); |
125 |
| - builder.getRawBeanDefinition().setSource(source); |
126 |
| - return builder; |
127 | 115 | }
|
128 | 116 |
|
129 | 117 | }
|
0 commit comments