|
22 | 22 | import java.lang.annotation.Target;
|
23 | 23 | import java.util.ArrayList;
|
24 | 24 | import java.util.List;
|
| 25 | +import java.util.Map; |
25 | 26 | import java.util.Optional;
|
26 | 27 |
|
| 28 | +import org.springframework.beans.factory.support.AbstractBeanDefinition; |
| 29 | +import org.springframework.beans.factory.support.BeanDefinitionBuilder; |
| 30 | +import org.springframework.beans.factory.support.BeanDefinitionRegistry; |
| 31 | +import org.springframework.beans.factory.support.BeanNameGenerator; |
27 | 32 | import org.springframework.context.ResourceLoaderAware;
|
28 | 33 | import org.springframework.context.annotation.Import;
|
| 34 | +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; |
29 | 35 | import org.springframework.context.annotation.ImportSelector;
|
30 | 36 | import org.springframework.core.io.ResourceLoader;
|
31 | 37 | import org.springframework.core.io.support.SpringFactoriesLoader;
|
32 | 38 | import org.springframework.core.type.AnnotationMetadata;
|
33 | 39 | import org.springframework.data.querydsl.QuerydslUtils;
|
34 |
| -import org.springframework.data.web.PageableHandlerMethodArgumentResolver; |
35 | 40 | import org.springframework.util.ClassUtils;
|
36 | 41 |
|
37 | 42 | /**
|
|
68 | 73 | @Retention(RetentionPolicy.RUNTIME)
|
69 | 74 | @Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
|
70 | 75 | @Inherited
|
71 |
| -@Import({ EnableSpringDataWebSupport.SpringDataWebConfigurationImportSelector.class, |
72 |
| - EnableSpringDataWebSupport.QuerydslActivator.class }) |
| 76 | +@Import({ |
| 77 | + EnableSpringDataWebSupport.SpringDataWebConfigurationImportSelector.class, |
| 78 | + EnableSpringDataWebSupport.QuerydslActivator.class, |
| 79 | + EnableSpringDataWebSupport.SpringDataWebSettingsRegistar.class |
| 80 | +}) |
73 | 81 | public @interface EnableSpringDataWebSupport {
|
74 | 82 |
|
| 83 | + /** |
| 84 | + * Configures how to render {@link org.springframework.data.domain.PageImpl} instances. Defaults to |
| 85 | + * {@link PageSerializationMode#DIRECT} for backward compatibility reasons. Prefer explicitly setting this to |
| 86 | + * {@link PageSerializationMode#VIA_DTO}, or manually convert {@link org.springframework.data.domain.PageImpl} |
| 87 | + * instances before handing them out of a controller method, either by manually calling {@code new PagedModel<>(page)} |
| 88 | + * or using Spring HATEOAS {@link org.springframework.hateoas.PagedModel} abstraction. |
| 89 | + * |
| 90 | + * @return will never be {@literal null}. |
| 91 | + * @since 3.3 |
| 92 | + */ |
| 93 | + PageSerializationMode pageSerializationMode() default PageSerializationMode.DIRECT; |
| 94 | + |
| 95 | + enum PageSerializationMode { |
| 96 | + |
| 97 | + /** |
| 98 | + * {@link org.springframework.data.domain.PageImpl} instances will be rendered as is (discouraged, as there's no |
| 99 | + * guarantee on the stability of the serialization result as we might need to change the type's API for unrelated |
| 100 | + * reasons). |
| 101 | + */ |
| 102 | + DIRECT, |
| 103 | + |
| 104 | + /** |
| 105 | + * Causes {@link org.springframework.data.domain.PageImpl} instances to be wrapped into |
| 106 | + * {@link org.springframework.data.web.PagedModel} instances before rendering them as JSON to make sure the |
| 107 | + * representation stays stable even if {@link org.springframework.data.domain.PageImpl} is changed. |
| 108 | + */ |
| 109 | + VIA_DTO; |
| 110 | + } |
| 111 | + |
75 | 112 | /**
|
76 | 113 | * Import selector to import the appropriate configuration class depending on whether Spring HATEOAS is present on the
|
77 | 114 | * classpath. We need to register the HATEOAS specific class first as apparently only the first class implementing
|
@@ -127,4 +164,39 @@ public String[] selectImports(AnnotationMetadata importingClassMetadata) {
|
127 | 164 | : new String[0];
|
128 | 165 | }
|
129 | 166 | }
|
| 167 | + |
| 168 | + /** |
| 169 | + * Registers a bean definition for {@link SpringDataWebSettings} carrying the configuration values of |
| 170 | + * {@link EnableSpringDataWebSupport}. |
| 171 | + * |
| 172 | + * @author Oliver Drotbohm |
| 173 | + * @soundtrack Norah Jones - Chasing Pirates |
| 174 | + * @since 3.3 |
| 175 | + */ |
| 176 | + static class SpringDataWebSettingsRegistar implements ImportBeanDefinitionRegistrar { |
| 177 | + |
| 178 | + /* |
| 179 | + * (non-Javadoc) |
| 180 | + * @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.beans.factory.support.BeanNameGenerator) |
| 181 | + */ |
| 182 | + @Override |
| 183 | + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, |
| 184 | + BeanNameGenerator importBeanNameGenerator) { |
| 185 | + |
| 186 | + Map<String, Object> attributes = importingClassMetadata |
| 187 | + .getAnnotationAttributes(EnableSpringDataWebSupport.class.getName()); |
| 188 | + |
| 189 | + if (attributes == null) { |
| 190 | + return; |
| 191 | + } |
| 192 | + |
| 193 | + AbstractBeanDefinition definition = BeanDefinitionBuilder.rootBeanDefinition(SpringDataWebSettings.class) |
| 194 | + .addConstructorArgValue(attributes.get("pageSerializationMode")) |
| 195 | + .getBeanDefinition(); |
| 196 | + |
| 197 | + String beanName = importBeanNameGenerator.generateBeanName(definition, registry); |
| 198 | + |
| 199 | + registry.registerBeanDefinition(beanName, definition); |
| 200 | + } |
| 201 | + } |
130 | 202 | }
|
0 commit comments