|
16 | 16 | package org.springframework.data.repository.config;
|
17 | 17 |
|
18 | 18 | import java.util.ArrayList;
|
19 |
| -import java.util.Collection; |
20 |
| -import java.util.Collections; |
21 | 19 | import java.util.List;
|
22 |
| -import java.util.function.Supplier; |
23 |
| -import java.util.stream.Collectors; |
24 | 20 |
|
| 21 | +import org.springframework.beans.factory.config.BeanDefinition; |
25 | 22 | import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
| 23 | +import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder; |
| 24 | +import org.springframework.beans.factory.config.RuntimeBeanReference; |
| 25 | +import org.springframework.beans.factory.support.RegisteredBean; |
| 26 | +import org.springframework.core.ResolvableType; |
| 27 | +import org.springframework.data.repository.CrudRepository; |
| 28 | +import org.springframework.data.repository.PagingAndSortingRepository; |
26 | 29 | import org.springframework.data.repository.core.RepositoryInformation;
|
27 |
| -import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; |
| 30 | +import org.springframework.data.repository.core.RepositoryMetadata; |
| 31 | +import org.springframework.data.repository.core.support.AbstractRepositoryMetadata; |
28 | 32 | import org.springframework.data.repository.core.support.RepositoryFragment;
|
29 |
| -import org.springframework.data.util.Lazy; |
| 33 | +import org.springframework.data.repository.core.support.RepositoryFragment.ImplementedRepositoryFragment; |
30 | 34 | import org.springframework.util.ClassUtils;
|
31 | 35 |
|
32 | 36 | /**
|
|
38 | 42 | */
|
39 | 43 | class RepositoryBeanDefinitionReader {
|
40 | 44 |
|
41 |
| - static RepositoryInformation readRepositoryInformation(RepositoryConfiguration<?> metadata, |
42 |
| - ConfigurableListableBeanFactory beanFactory) { |
43 |
| - |
44 |
| - return new AotRepositoryInformation(metadataSupplier(metadata, beanFactory), |
45 |
| - repositoryBaseClass(metadata, beanFactory), fragments(metadata, beanFactory)); |
| 45 | + /** |
| 46 | + * @return |
| 47 | + */ |
| 48 | + static RepositoryInformation repositoryInformation(RepositoryConfiguration<?> repoConfig, RegisteredBean repoBean) { |
| 49 | + return repositoryInformation(repoConfig, repoBean.getMergedBeanDefinition(), repoBean.getBeanFactory()); |
46 | 50 | }
|
47 | 51 |
|
48 |
| - private static Supplier<Collection<RepositoryFragment<?>>> fragments(RepositoryConfiguration<?> metadata, |
| 52 | + /** |
| 53 | + * @param source the RepositoryFactoryBeanSupport bean definition. |
| 54 | + * @param beanFactory |
| 55 | + * @return |
| 56 | + */ |
| 57 | + @SuppressWarnings("NullAway") |
| 58 | + static RepositoryInformation repositoryInformation(RepositoryConfiguration<?> repoConfig, BeanDefinition source, |
49 | 59 | ConfigurableListableBeanFactory beanFactory) {
|
50 | 60 |
|
51 |
| - if (metadata instanceof RepositoryFragmentConfigurationProvider provider) { |
52 |
| - |
53 |
| - return Lazy.of(() -> { |
54 |
| - return provider.getFragmentConfiguration().stream().flatMap(it -> { |
55 |
| - |
56 |
| - List<RepositoryFragment<?>> fragments = new ArrayList<>(1); |
| 61 | + RepositoryMetadata metadata = AbstractRepositoryMetadata |
| 62 | + .getMetadata(forName(repoConfig.getRepositoryInterface(), beanFactory)); |
| 63 | + Class<?> repositoryBaseClass = readRepositoryBaseClass(source, beanFactory); |
| 64 | + List<RepositoryFragment<?>> fragmentList = readRepositoryFragments(source, beanFactory); |
| 65 | + if (source.getPropertyValues().contains("customImplementation")) { |
| 66 | + |
| 67 | + Object o = source.getPropertyValues().get("customImplementation"); |
| 68 | + if (o instanceof RuntimeBeanReference rbr) { |
| 69 | + BeanDefinition customImplBeanDefintion = beanFactory.getBeanDefinition(rbr.getBeanName()); |
| 70 | + Class<?> beanType = forName(customImplBeanDefintion.getBeanClassName(), beanFactory); |
| 71 | + ResolvableType[] interfaces = ResolvableType.forClass(beanType).getInterfaces(); |
| 72 | + if (interfaces.length == 1) { |
| 73 | + fragmentList.add(new ImplementedRepositoryFragment(interfaces[0].toClass(), beanType)); |
| 74 | + } else { |
| 75 | + boolean found = false; |
| 76 | + for (ResolvableType i : interfaces) { |
| 77 | + if (beanType.getSimpleName().contains(i.resolve().getSimpleName())) { |
| 78 | + fragmentList.add(new ImplementedRepositoryFragment(interfaces[0].toClass(), beanType)); |
| 79 | + found = true; |
| 80 | + break; |
| 81 | + } |
| 82 | + } |
| 83 | + if (!found) { |
| 84 | + fragmentList.add(RepositoryFragment.implemented(beanType)); |
| 85 | + } |
| 86 | + } |
| 87 | + } |
| 88 | + } |
57 | 89 |
|
58 |
| - fragments.add(RepositoryFragment.implemented(forName(it.getClassName(), beanFactory))); |
| 90 | + String moduleName = (String) source.getPropertyValues().get("moduleName"); |
| 91 | + AotRepositoryInformation repositoryInformation = new AotRepositoryInformation(moduleName, () -> metadata, |
| 92 | + () -> repositoryBaseClass, () -> fragmentList); |
| 93 | + return repositoryInformation; |
| 94 | + } |
59 | 95 |
|
60 |
| - if (it.getInterfaceName() != null) { |
61 |
| - fragments.add(RepositoryFragment.structural(forName(it.getInterfaceName(), beanFactory))); |
62 |
| - } |
| 96 | + @SuppressWarnings("NullAway") |
| 97 | + private static Class<?> readRepositoryBaseClass(BeanDefinition source, ConfigurableListableBeanFactory beanFactory) { |
63 | 98 |
|
64 |
| - return fragments.stream(); |
65 |
| - }).collect(Collectors.toList()); |
66 |
| - }); |
| 99 | + Object repoBaseClassName = source.getPropertyValues().get("repositoryBaseClass"); |
| 100 | + if (repoBaseClassName != null) { |
| 101 | + return forName(repoBaseClassName.toString(), beanFactory); |
67 | 102 | }
|
68 |
| - |
69 |
| - return Lazy.of(Collections::emptyList); |
| 103 | + if (source.getPropertyValues().contains("moduleBaseClass")) { |
| 104 | + return forName((String) source.getPropertyValues().get("moduleBaseClass"), beanFactory); |
| 105 | + } |
| 106 | + return Dummy.class; |
70 | 107 | }
|
71 | 108 |
|
72 |
| - @SuppressWarnings({ "rawtypes", "unchecked" }) |
73 |
| - private static Supplier<Class<?>> repositoryBaseClass(RepositoryConfiguration metadata, |
| 109 | + @SuppressWarnings("NullAway") |
| 110 | + private static List<RepositoryFragment<?>> readRepositoryFragments(BeanDefinition source, |
74 | 111 | ConfigurableListableBeanFactory beanFactory) {
|
75 | 112 |
|
76 |
| - return Lazy.of(() -> (Class<?>) metadata.getRepositoryBaseClassName().map(it -> forName(it.toString(), beanFactory)) |
77 |
| - .orElse(Object.class)); |
| 113 | + RuntimeBeanReference beanReference = (RuntimeBeanReference) source.getPropertyValues().get("repositoryFragments"); |
| 114 | + BeanDefinition fragments = beanFactory.getBeanDefinition(beanReference.getBeanName()); |
| 115 | + |
| 116 | + ValueHolder fragmentBeanNameList = fragments.getConstructorArgumentValues().getArgumentValue(0, List.class); |
| 117 | + List<String> fragmentBeanNames = (List<String>) fragmentBeanNameList.getValue(); |
| 118 | + |
| 119 | + List<RepositoryFragment<?>> fragmentList = new ArrayList<>(); |
| 120 | + for (String beanName : fragmentBeanNames) { |
| 121 | + |
| 122 | + BeanDefinition fragmentBeanDefinition = beanFactory.getBeanDefinition(beanName); |
| 123 | + ValueHolder argumentValue = fragmentBeanDefinition.getConstructorArgumentValues().getArgumentValue(0, |
| 124 | + String.class); |
| 125 | + ValueHolder argumentValue1 = fragmentBeanDefinition.getConstructorArgumentValues().getArgumentValue(1, null, null, |
| 126 | + null); |
| 127 | + Object fragmentClassName = argumentValue.getValue(); |
| 128 | + |
| 129 | + try { |
| 130 | + Class<?> type = ClassUtils.forName(fragmentClassName.toString(), beanFactory.getBeanClassLoader()); |
| 131 | + |
| 132 | + if (argumentValue1 != null && argumentValue1.getValue() instanceof RuntimeBeanReference rbf) { |
| 133 | + BeanDefinition implBeanDef = beanFactory.getBeanDefinition(rbf.getBeanName()); |
| 134 | + Class implClass = ClassUtils.forName(implBeanDef.getBeanClassName(), beanFactory.getBeanClassLoader()); |
| 135 | + fragmentList.add(new RepositoryFragment.ImplementedRepositoryFragment(type, implClass)); |
| 136 | + } else { |
| 137 | + fragmentList.add(RepositoryFragment.structural(type)); |
| 138 | + } |
| 139 | + } catch (ClassNotFoundException e) { |
| 140 | + throw new RuntimeException(e); |
| 141 | + } |
| 142 | + } |
| 143 | + return fragmentList; |
78 | 144 | }
|
79 | 145 |
|
80 |
| - private static Supplier<org.springframework.data.repository.core.RepositoryMetadata> metadataSupplier( |
81 |
| - RepositoryConfiguration<?> metadata, ConfigurableListableBeanFactory beanFactory) { |
82 |
| - return Lazy.of(() -> new DefaultRepositoryMetadata(forName(metadata.getRepositoryInterface(), beanFactory))); |
83 |
| - } |
| 146 | + static abstract class Dummy implements CrudRepository<Object, Object>, PagingAndSortingRepository<Object, Object> {} |
84 | 147 |
|
85 | 148 | static Class<?> forName(String name, ConfigurableListableBeanFactory beanFactory) {
|
86 | 149 | try {
|
|
0 commit comments