Skip to content

Commit c1a74de

Browse files
committed
Boolean getLazyInit accessor indicating no explicit flag set
Closes gh-22694
1 parent 03bda29 commit c1a74de

File tree

3 files changed

+121
-25
lines changed

3 files changed

+121
-25
lines changed

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

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
145145

146146
private boolean abstractFlag = false;
147147

148-
private boolean lazyInit = false;
148+
@Nullable
149+
private Boolean lazyInit;
149150

150151
private int autowireMode = AUTOWIRE_NO;
151152

@@ -229,7 +230,6 @@ protected AbstractBeanDefinition(BeanDefinition original) {
229230
setBeanClassName(original.getBeanClassName());
230231
setScope(original.getScope());
231232
setAbstract(original.isAbstract());
232-
setLazyInit(original.isLazyInit());
233233
setFactoryBeanName(original.getFactoryBeanName());
234234
setFactoryMethodName(original.getFactoryMethodName());
235235
setRole(original.getRole());
@@ -250,6 +250,10 @@ protected AbstractBeanDefinition(BeanDefinition original) {
250250
if (originalAbd.hasMethodOverrides()) {
251251
setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides()));
252252
}
253+
Boolean lazyInit = originalAbd.getLazyInit();
254+
if (lazyInit != null) {
255+
setLazyInit(lazyInit);
256+
}
253257
setAutowireMode(originalAbd.getAutowireMode());
254258
setDependencyCheck(originalAbd.getDependencyCheck());
255259
setDependsOn(originalAbd.getDependsOn());
@@ -269,6 +273,7 @@ protected AbstractBeanDefinition(BeanDefinition original) {
269273
else {
270274
setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
271275
setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
276+
setLazyInit(original.isLazyInit());
272277
setResourceDescription(original.getResourceDescription());
273278
}
274279
}
@@ -298,7 +303,6 @@ public void overrideFrom(BeanDefinition other) {
298303
setScope(other.getScope());
299304
}
300305
setAbstract(other.isAbstract());
301-
setLazyInit(other.isLazyInit());
302306
if (StringUtils.hasLength(other.getFactoryBeanName())) {
303307
setFactoryBeanName(other.getFactoryBeanName());
304308
}
@@ -323,6 +327,10 @@ public void overrideFrom(BeanDefinition other) {
323327
if (otherAbd.hasMethodOverrides()) {
324328
getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
325329
}
330+
Boolean lazyInit = otherAbd.getLazyInit();
331+
if (lazyInit != null) {
332+
setLazyInit(lazyInit);
333+
}
326334
setAutowireMode(otherAbd.getAutowireMode());
327335
setDependencyCheck(otherAbd.getDependencyCheck());
328336
setDependsOn(otherAbd.getDependsOn());
@@ -346,16 +354,21 @@ public void overrideFrom(BeanDefinition other) {
346354
else {
347355
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
348356
getPropertyValues().addPropertyValues(other.getPropertyValues());
357+
setLazyInit(other.isLazyInit());
349358
setResourceDescription(other.getResourceDescription());
350359
}
351360
}
352361

353362
/**
354363
* Apply the provided default values to this bean.
355-
* @param defaults the defaults to apply
364+
* @param defaults the default settings to apply
365+
* @since 2.5
356366
*/
357367
public void applyDefaults(BeanDefinitionDefaults defaults) {
358-
setLazyInit(defaults.isLazyInit());
368+
Boolean lazyInit = defaults.getLazyInit();
369+
if (lazyInit != null) {
370+
setLazyInit(lazyInit);
371+
}
359372
setAutowireMode(defaults.getAutowireMode());
360373
setDependencyCheck(defaults.getDependencyCheck());
361374
setInitMethodName(defaults.getInitMethodName());
@@ -515,16 +528,29 @@ public void setLazyInit(boolean lazyInit) {
515528
/**
516529
* Return whether this bean should be lazily initialized, i.e. not
517530
* eagerly instantiated on startup. Only applicable to a singleton bean.
531+
* @return whether to apply lazy-init semantics ({@code false} by default)
518532
*/
519533
@Override
520534
public boolean isLazyInit() {
535+
return (this.lazyInit != null && this.lazyInit.booleanValue());
536+
}
537+
538+
/**
539+
* Return whether this bean should be lazily initialized, i.e. not
540+
* eagerly instantiated on startup. Only applicable to a singleton bean.
541+
* @return the lazy-init flag if explicitly set, or {@code null} otherwise
542+
* @since 5.2
543+
*/
544+
@Nullable
545+
public Boolean getLazyInit() {
521546
return this.lazyInit;
522547
}
523548

524549
/**
525550
* Set the autowire mode. This determines whether any automagical detection
526-
* and setting of bean references will happen. Default is AUTOWIRE_NO,
527-
* which means there's no autowire.
551+
* and setting of bean references will happen. Default is AUTOWIRE_NO
552+
* which means there won't be convention-based autowiring by name or type
553+
* (however, there may still be explicit annotation-driven autowiring).
528554
* @param autowireMode the autowire mode to set.
529555
* Must be one of the constants defined in this class.
530556
* @see #AUTOWIRE_NO

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

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,60 +23,114 @@
2323
* A simple holder for {@code BeanDefinition} property defaults.
2424
*
2525
* @author Mark Fisher
26+
* @author Juergen Hoeller
2627
* @since 2.5
2728
*/
2829
public class BeanDefinitionDefaults {
2930

30-
private boolean lazyInit;
31-
32-
private int dependencyCheck = AbstractBeanDefinition.DEPENDENCY_CHECK_NONE;
31+
@Nullable
32+
private Boolean lazyInit;
3333

3434
private int autowireMode = AbstractBeanDefinition.AUTOWIRE_NO;
3535

36+
private int dependencyCheck = AbstractBeanDefinition.DEPENDENCY_CHECK_NONE;
37+
3638
@Nullable
3739
private String initMethodName;
3840

3941
@Nullable
4042
private String destroyMethodName;
4143

4244

45+
/**
46+
* Set whether beans should be lazily initialized by default.
47+
* <p>If {@code false}, the bean will get instantiated on startup by bean
48+
* factories that perform eager initialization of singletons.
49+
*/
4350
public void setLazyInit(boolean lazyInit) {
4451
this.lazyInit = lazyInit;
4552
}
4653

54+
/**
55+
* Return whether beans should be lazily initialized by default, i.e. not
56+
* eagerly instantiated on startup. Only applicable to singleton beans.
57+
* @return whether to apply lazy-init semantics ({@code false} by default)
58+
*/
4759
public boolean isLazyInit() {
48-
return this.lazyInit;
60+
return (this.lazyInit != null && this.lazyInit.booleanValue());
4961
}
5062

51-
public void setDependencyCheck(int dependencyCheck) {
52-
this.dependencyCheck = dependencyCheck;
53-
}
54-
55-
public int getDependencyCheck() {
56-
return this.dependencyCheck;
63+
/**
64+
* Return whether beans should be lazily initialized by default, i.e. not
65+
* eagerly instantiated on startup. Only applicable to singleton beans.
66+
* @return the lazy-init flag if explicitly set, or {@code null} otherwise
67+
* @since 5.2
68+
*/
69+
@Nullable
70+
public Boolean getLazyInit() {
71+
return this.lazyInit;
5772
}
5873

74+
/**
75+
* Set the autowire mode. This determines whether any automagical detection
76+
* and setting of bean references will happen. Default is AUTOWIRE_NO
77+
* which means there won't be convention-based autowiring by name or type
78+
* (however, there may still be explicit annotation-driven autowiring).
79+
* @param autowireMode the autowire mode to set.
80+
* Must be one of the constants defined in {@link AbstractBeanDefinition}.
81+
*/
5982
public void setAutowireMode(int autowireMode) {
6083
this.autowireMode = autowireMode;
6184
}
6285

86+
/**
87+
* Return the default autowire mode.
88+
*/
6389
public int getAutowireMode() {
6490
return this.autowireMode;
6591
}
6692

93+
/**
94+
* Set the dependency check code.
95+
* @param dependencyCheck the code to set.
96+
* Must be one of the constants defined in {@link AbstractBeanDefinition}.
97+
*/
98+
public void setDependencyCheck(int dependencyCheck) {
99+
this.dependencyCheck = dependencyCheck;
100+
}
101+
102+
/**
103+
* Return the default dependency check code.
104+
*/
105+
public int getDependencyCheck() {
106+
return this.dependencyCheck;
107+
}
108+
109+
/**
110+
* Set the name of the default initializer method.
111+
*/
67112
public void setInitMethodName(@Nullable String initMethodName) {
68113
this.initMethodName = (StringUtils.hasText(initMethodName) ? initMethodName : null);
69114
}
70115

116+
/**
117+
* Return the name of the default initializer method.
118+
*/
71119
@Nullable
72120
public String getInitMethodName() {
73121
return this.initMethodName;
74122
}
75123

124+
/**
125+
* Set the name of the default destroy method.
126+
*/
76127
public void setDestroyMethodName(@Nullable String destroyMethodName) {
77128
this.destroyMethodName = (StringUtils.hasText(destroyMethodName) ? destroyMethodName : null);
78129
}
79130

131+
/**
132+
* Return the name of the default destroy method.
133+
*/
80134
@Nullable
81135
public String getDestroyMethodName() {
82136
return this.destroyMethodName;

spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,6 +2353,27 @@ public void testPrototypeFactoryBeanNotEagerlyCalled() {
23532353
lbf.preInstantiateSingletons();
23542354
}
23552355

2356+
@Test
2357+
public void testLazyInitFlag() {
2358+
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
2359+
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
2360+
bd1.setLazyInit(true);
2361+
factory.registerBeanDefinition("tb1", bd1);
2362+
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
2363+
bd2.setLazyInit(false);
2364+
factory.registerBeanDefinition("tb2", bd2);
2365+
factory.registerBeanDefinition("tb3", new RootBeanDefinition(TestBean.class));
2366+
2367+
assertEquals(Boolean.TRUE, ((AbstractBeanDefinition) factory.getMergedBeanDefinition("tb1")).getLazyInit());
2368+
assertEquals(Boolean.FALSE, ((AbstractBeanDefinition) factory.getMergedBeanDefinition("tb2")).getLazyInit());
2369+
assertNull(((AbstractBeanDefinition) factory.getMergedBeanDefinition("tb3")).getLazyInit());
2370+
2371+
factory.preInstantiateSingletons();
2372+
assertFalse(factory.containsSingleton("tb1"));
2373+
assertTrue(factory.containsSingleton("tb2"));
2374+
assertTrue(factory.containsSingleton("tb3"));
2375+
}
2376+
23562377
@Test
23572378
public void testLazyInitFactory() {
23582379
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
@@ -2877,8 +2898,8 @@ public boolean postProcessAfterInstantiation(Object bean, String beanName) throw
28772898
}
28782899
}
28792900

2880-
@SuppressWarnings("unchecked")
28812901
@Test
2902+
@SuppressWarnings("unchecked")
28822903
public void testInitSecurityAwarePrototypeBean() {
28832904
final DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
28842905
RootBeanDefinition bd = new RootBeanDefinition(TestSecuredBean.class);
@@ -2889,12 +2910,7 @@ public void testInitSecurityAwarePrototypeBean() {
28892910
subject.getPrincipals().add(new TestPrincipal("user1"));
28902911

28912912
TestSecuredBean bean = (TestSecuredBean) Subject.doAsPrivileged(subject,
2892-
new PrivilegedAction() {
2893-
@Override
2894-
public Object run() {
2895-
return lbf.getBean("test");
2896-
}
2897-
}, null);
2913+
(PrivilegedAction) () -> lbf.getBean("test"), null);
28982914
assertNotNull(bean);
28992915
assertEquals("user1", bean.getUserName());
29002916
}

0 commit comments

Comments
 (0)