Skip to content

Commit bd88554

Browse files
committed
Allow chained BeanRegistry registration
Add a `register(BeanRegistry registry)` method to `BeanRegistry` to allow registration chaining.
1 parent 86d8163 commit bd88554

File tree

5 files changed

+55
-27
lines changed

5 files changed

+55
-27
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/BeanRegistry.java

+7
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ public interface BeanRegistry {
7777
*/
7878
<T> void registerBean(String name, Class<T> beanClass, Consumer<Spec<T>> customizer);
7979

80+
/**
81+
* Register beans using given {@link BeanRegistrar}.
82+
* @param registrar the bean registrar that will be called to register
83+
* additional beans
84+
*/
85+
void register(BeanRegistrar registrar);
86+
8087
/**
8188
* Specification for customizing a bean.
8289
* @param <T> the bean type

spring-beans/src/main/java/org/springframework/beans/factory/support/BeanRegistryAdapter.java

+16-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.springframework.beans.factory.config.BeanDefinition;
3232
import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
3333
import org.springframework.core.ResolvableType;
34+
import org.springframework.core.env.Environment;
35+
import org.springframework.util.Assert;
3436
import org.springframework.util.MultiValueMap;
3537

3638
/**
@@ -46,21 +48,26 @@ public class BeanRegistryAdapter implements BeanRegistry {
4648

4749
private final ListableBeanFactory beanFactory;
4850

51+
private final Environment environment;
52+
4953
private final Class<? extends BeanRegistrar> beanRegistrarClass;
5054

5155
private final @Nullable MultiValueMap<String, BeanDefinitionCustomizer> customizers;
5256

5357

5458
public BeanRegistryAdapter(BeanDefinitionRegistry beanRegistry, ListableBeanFactory beanFactory,
55-
Class<? extends BeanRegistrar> beanRegistrarClass) {
56-
this(beanRegistry, beanFactory, beanRegistrarClass, null);
59+
Environment environment, Class<? extends BeanRegistrar> beanRegistrarClass) {
60+
61+
this(beanRegistry, beanFactory, environment, beanRegistrarClass, null);
5762
}
5863

5964
public BeanRegistryAdapter(BeanDefinitionRegistry beanRegistry, ListableBeanFactory beanFactory,
60-
Class<? extends BeanRegistrar> beanRegistrarClass, @Nullable MultiValueMap<String, BeanDefinitionCustomizer> customizers) {
65+
Environment environment, Class<? extends BeanRegistrar> beanRegistrarClass,
66+
@Nullable MultiValueMap<String, BeanDefinitionCustomizer> customizers) {
6167

6268
this.beanRegistry = beanRegistry;
6369
this.beanFactory = beanFactory;
70+
this.environment = environment;
6471
this.beanRegistrarClass = beanRegistrarClass;
6572
this.customizers = customizers;
6673
}
@@ -102,6 +109,12 @@ public <T> void registerBean(String name, Class<T> beanClass, Consumer<Spec<T>>
102109
this.beanRegistry.registerBeanDefinition(name, beanDefinition);
103110
}
104111

112+
@Override
113+
public void register(BeanRegistrar registrar) {
114+
Assert.notNull(registrar, "'registrar' must not be null");
115+
registrar.register(this, this.environment);
116+
}
117+
105118

106119
/**
107120
* {@link RootBeanDefinition} subclass for {@code #registerBean} based

spring-beans/src/test/java/org/springframework/beans/factory/support/BeanRegistryAdapterTests.java

+28-20
Original file line numberDiff line numberDiff line change
@@ -41,103 +41,103 @@ public class BeanRegistryAdapterTests {
4141

4242
@Test
4343
void defaultBackgroundInit() {
44-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, DefaultBeanRegistrar.class);
44+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, DefaultBeanRegistrar.class);
4545
new DefaultBeanRegistrar().register(adapter, env);
4646
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) this.beanFactory.getBeanDefinition("foo");
4747
assertThat(beanDefinition.isBackgroundInit()).isFalse();
4848
}
4949

5050
@Test
5151
void enableBackgroundInit() {
52-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, BackgroundInitBeanRegistrar.class);
52+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, BackgroundInitBeanRegistrar.class);
5353
new BackgroundInitBeanRegistrar().register(adapter, env);
5454
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) this.beanFactory.getBeanDefinition("foo");
5555
assertThat(beanDefinition.isBackgroundInit()).isTrue();
5656
}
5757

5858
@Test
5959
void defaultDescription() {
60-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, DefaultBeanRegistrar.class);
60+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, DefaultBeanRegistrar.class);
6161
new DefaultBeanRegistrar().register(adapter, env);
6262
BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition("foo");
6363
assertThat(beanDefinition.getDescription()).isNull();
6464
}
6565

6666
@Test
6767
void customDescription() {
68-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, CustomDescriptionBeanRegistrar.class);
68+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, CustomDescriptionBeanRegistrar.class);
6969
new CustomDescriptionBeanRegistrar().register(adapter, env);
7070
BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition("foo");
7171
assertThat(beanDefinition.getDescription()).isEqualTo("custom");
7272
}
7373

7474
@Test
7575
void defaultFallback() {
76-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, DefaultBeanRegistrar.class);
76+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, DefaultBeanRegistrar.class);
7777
new DefaultBeanRegistrar().register(adapter, env);
7878
BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition("foo");
7979
assertThat(beanDefinition.isFallback()).isFalse();
8080
}
8181

8282
@Test
8383
void enableFallback() {
84-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, FallbackBeanRegistrar.class);
84+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, FallbackBeanRegistrar.class);
8585
new FallbackBeanRegistrar().register(adapter, env);
8686
BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition("foo");
8787
assertThat(beanDefinition.isFallback()).isTrue();
8888
}
8989

9090
@Test
9191
void defaultRole() {
92-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, DefaultBeanRegistrar.class);
92+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, DefaultBeanRegistrar.class);
9393
new DefaultBeanRegistrar().register(adapter, env);
9494
BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition("foo");
9595
assertThat(beanDefinition.getRole()).isEqualTo(AbstractBeanDefinition.ROLE_APPLICATION);
9696
}
9797

9898
@Test
9999
void infrastructureRole() {
100-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, InfrastructureBeanRegistrar.class);
100+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, InfrastructureBeanRegistrar.class);
101101
new InfrastructureBeanRegistrar().register(adapter, env);
102102
BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition("foo");
103103
assertThat(beanDefinition.getRole()).isEqualTo(AbstractBeanDefinition.ROLE_INFRASTRUCTURE);
104104
}
105105

106106
@Test
107107
void defaultLazyInit() {
108-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, DefaultBeanRegistrar.class);
108+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, DefaultBeanRegistrar.class);
109109
new DefaultBeanRegistrar().register(adapter, env);
110110
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) this.beanFactory.getBeanDefinition("foo");
111111
assertThat(beanDefinition.isLazyInit()).isFalse();
112112
}
113113

114114
@Test
115115
void enableLazyInit() {
116-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, LazyInitBeanRegistrar.class);
116+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, LazyInitBeanRegistrar.class);
117117
new LazyInitBeanRegistrar().register(adapter, env);
118118
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) this.beanFactory.getBeanDefinition("foo");
119119
assertThat(beanDefinition.isLazyInit()).isTrue();
120120
}
121121

122122
@Test
123123
void defaultAutowirable() {
124-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, DefaultBeanRegistrar.class);
124+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, DefaultBeanRegistrar.class);
125125
new DefaultBeanRegistrar().register(adapter, env);
126126
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) this.beanFactory.getBeanDefinition("foo");
127127
assertThat(beanDefinition.isAutowireCandidate()).isTrue();
128128
}
129129

130130
@Test
131131
void notAutowirable() {
132-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, NotAutowirableBeanRegistrar.class);
132+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, NotAutowirableBeanRegistrar.class);
133133
new NotAutowirableBeanRegistrar().register(adapter, env);
134134
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) this.beanFactory.getBeanDefinition("foo");
135135
assertThat(beanDefinition.isAutowireCandidate()).isFalse();
136136
}
137137

138138
@Test
139139
void defaultOrder() {
140-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, DefaultBeanRegistrar.class);
140+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, DefaultBeanRegistrar.class);
141141
new DefaultBeanRegistrar().register(adapter, env);
142142
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) this.beanFactory.getBeanDefinition("foo");
143143
Integer order = (Integer)beanDefinition.getAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE);
@@ -146,7 +146,7 @@ void defaultOrder() {
146146

147147
@Test
148148
void customOrder() {
149-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, CustomOrderBeanRegistrar.class);
149+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, CustomOrderBeanRegistrar.class);
150150
new CustomOrderBeanRegistrar().register(adapter, env);
151151
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) this.beanFactory.getBeanDefinition("foo");
152152
Integer order = (Integer)beanDefinition.getAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE);
@@ -155,54 +155,62 @@ void customOrder() {
155155

156156
@Test
157157
void defaultPrimary() {
158-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, DefaultBeanRegistrar.class);
158+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, DefaultBeanRegistrar.class);
159159
new DefaultBeanRegistrar().register(adapter, env);
160160
BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition("foo");
161161
assertThat(beanDefinition.isPrimary()).isFalse();
162162
}
163163

164164
@Test
165165
void enablePrimary() {
166-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, PrimaryBeanRegistrar.class);
166+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, PrimaryBeanRegistrar.class);
167167
new PrimaryBeanRegistrar().register(adapter, env);
168168
BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition("foo");
169169
assertThat(beanDefinition.isPrimary()).isTrue();
170170
}
171171

172172
@Test
173173
void defaultScope() {
174-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, DefaultBeanRegistrar.class);
174+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, DefaultBeanRegistrar.class);
175175
new DefaultBeanRegistrar().register(adapter, env);
176176
BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition("foo");
177177
assertThat(beanDefinition.getScope()).isEqualTo(AbstractBeanDefinition.SCOPE_DEFAULT);
178178
}
179179

180180
@Test
181181
void prototypeScope() {
182-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, PrototypeBeanRegistrar.class);
182+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, PrototypeBeanRegistrar.class);
183183
new PrototypeBeanRegistrar().register(adapter, env);
184184
BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition("foo");
185185
assertThat(beanDefinition.getScope()).isEqualTo(AbstractBeanDefinition.SCOPE_PROTOTYPE);
186186
}
187187

188188
@Test
189189
void defaultSupplier() {
190-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, DefaultBeanRegistrar.class);
190+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, DefaultBeanRegistrar.class);
191191
new DefaultBeanRegistrar().register(adapter, env);
192192
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition)this.beanFactory.getBeanDefinition("foo");
193193
assertThat(beanDefinition.getInstanceSupplier()).isNull();
194194
}
195195

196196
@Test
197197
void customSupplier() {
198-
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, SupplierBeanRegistrar.class);
198+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, SupplierBeanRegistrar.class);
199199
new SupplierBeanRegistrar().register(adapter, env);
200200
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition)this.beanFactory.getBeanDefinition("foo");
201201
Supplier<?> supplier = beanDefinition.getInstanceSupplier();
202202
assertThat(supplier).isNotNull();
203203
assertThat(supplier.get()).isNotNull().isInstanceOf(Foo.class);
204204
}
205205

206+
@Test
207+
void registerViaAnotherRegistrar() {
208+
BeanRegistryAdapter adapter = new BeanRegistryAdapter(this.beanFactory, this.beanFactory, this.env, DefaultBeanRegistrar.class);
209+
BeanRegistrar registrar = (registry, env) -> registry.register(new DefaultBeanRegistrar());
210+
registrar.register(adapter, env);
211+
assertThat(this.beanFactory.getBeanDefinition("foo")).isNotNull();
212+
}
213+
206214

207215
private static class DefaultBeanRegistrar implements BeanRegistrar {
208216

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ private void loadBeanDefinitionsFromBeanRegistrars(Set<BeanRegistrar> registrars
409409
"Cannot support bean registrars since " + this.registry.getClass().getName() +
410410
" does not implement BeanDefinitionRegistry");
411411
registrars.forEach(registrar -> registrar.register(new BeanRegistryAdapter(this.registry,
412-
(ListableBeanFactory) this.registry, registrar.getClass()), this.environment));
412+
(ListableBeanFactory) this.registry, this.environment, registrar.getClass()), this.environment));
413413
}
414414

415415

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -936,10 +936,10 @@ private CodeBlock generateCustomizerMap() {
936936
private CodeBlock generateRegisterCode() {
937937
Builder code = CodeBlock.builder();
938938
for (BeanRegistrar beanRegistrar : this.beanRegistrars) {
939-
code.addStatement("new $T().register(new $T(($T)$L, $L, $T.class, $L), $L)", beanRegistrar.getClass(),
939+
code.addStatement("new $T().register(new $T(($T)$L, $L, $L, $T.class, $L), $L)", beanRegistrar.getClass(),
940940
BeanRegistryAdapter.class, BeanDefinitionRegistry.class, BeanFactoryInitializationCode.BEAN_FACTORY_VARIABLE,
941-
BeanFactoryInitializationCode.BEAN_FACTORY_VARIABLE, beanRegistrar.getClass(), CUSTOMIZER_MAP_VARIABLE,
942-
ENVIRONMENT_VARIABLE);
941+
BeanFactoryInitializationCode.BEAN_FACTORY_VARIABLE, ENVIRONMENT_VARIABLE, beanRegistrar.getClass(),
942+
CUSTOMIZER_MAP_VARIABLE, ENVIRONMENT_VARIABLE);
943943
}
944944
return code.build();
945945
}

0 commit comments

Comments
 (0)