Skip to content

Commit 626a4da

Browse files
committed
Skip lazy init for beans that explicitly set lazy to false
Fixes spring-projectsgh-16184
1 parent 7587af3 commit 626a4da

File tree

5 files changed

+104
-1
lines changed

5 files changed

+104
-1
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.springframework.context.ApplicationListener;
3636
import org.springframework.context.ConfigurableApplicationContext;
3737
import org.springframework.context.annotation.Configuration;
38+
import org.springframework.context.annotation.Lazy;
3839
import org.springframework.context.event.ContextClosedEvent;
3940
import org.springframework.core.Ordered;
4041
import org.springframework.core.env.ConfigurableEnvironment;
@@ -121,6 +122,7 @@ static class EnableSameManagementContextConfiguration {
121122

122123
@Configuration(proxyBeanMethods = false)
123124
@ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
125+
@Lazy(false)
124126
static class DifferentManagementContextConfiguration
125127
implements SmartInitializingSingleton {
126128

spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ on `SpringApplicationBuilder` or the `setLazyInitialization` method on
119119
spring.main.lazy-initialization=true
120120
----
121121

122+
TIP: If you want to disable lazy initialization for certain beans while using lazy
123+
initialization for the rest of the application, you can explicitly set their lazy attribute
124+
to false using the `@Lazy(false)` annotation.
125+
122126

123127

124128
[[boot-features-banner]]

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
4141
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
4242
import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
43+
import org.springframework.beans.factory.support.AbstractBeanDefinition;
4344
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
4445
import org.springframework.beans.factory.support.BeanNameGenerator;
4546
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
@@ -1352,7 +1353,15 @@ private static final class LazyInitializationBeanFactoryPostProcessor
13521353
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
13531354
throws BeansException {
13541355
for (String name : beanFactory.getBeanDefinitionNames()) {
1355-
beanFactory.getBeanDefinition(name).setLazyInit(true);
1356+
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
1357+
if (beanDefinition instanceof AbstractBeanDefinition) {
1358+
Boolean lazyInit = ((AbstractBeanDefinition) beanDefinition)
1359+
.getLazyInit();
1360+
if (lazyInit != null && !lazyInit) {
1361+
continue;
1362+
}
1363+
}
1364+
beanDefinition.setLazyInit(true);
13561365
}
13571366
}
13581367

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
import org.springframework.context.annotation.AnnotationConfigUtils;
7575
import org.springframework.context.annotation.Bean;
7676
import org.springframework.context.annotation.Configuration;
77+
import org.springframework.context.annotation.Lazy;
7778
import org.springframework.context.event.ApplicationEventMulticaster;
7879
import org.springframework.context.event.ContextRefreshedEvent;
7980
import org.springframework.context.event.SimpleApplicationEventMulticaster;
@@ -1186,6 +1187,14 @@ public void lazyInitializationCanBeEnabled() {
11861187
.getBean(AtomicInteger.class)).hasValue(0);
11871188
}
11881189

1190+
@Test
1191+
public void lazyInitializationShouldNotApplyToBeansThatAreExplicitlyNotLazy() {
1192+
assertThat(new SpringApplication(NotLazyInitializationConfig.class)
1193+
.run("--spring.main.web-application-type=none",
1194+
"--spring.main.lazy-initialization=true")
1195+
.getBean(AtomicInteger.class)).hasValue(1);
1196+
}
1197+
11891198
private Condition<ConfigurableEnvironment> matchingPropertySource(
11901199
final Class<?> propertySourceClass, final String name) {
11911200
return new Condition<ConfigurableEnvironment>("has property source") {
@@ -1475,6 +1484,30 @@ static class LazyBean {
14751484

14761485
}
14771486

1487+
@Configuration(proxyBeanMethods = false)
1488+
static class NotLazyInitializationConfig {
1489+
1490+
@Bean
1491+
public AtomicInteger counter() {
1492+
return new AtomicInteger(0);
1493+
}
1494+
1495+
@Bean
1496+
@Lazy(false)
1497+
public NotLazyBean NotLazyBean(AtomicInteger counter) {
1498+
return new NotLazyBean(counter);
1499+
}
1500+
1501+
static class NotLazyBean {
1502+
1503+
NotLazyBean(AtomicInteger counter) {
1504+
counter.getAndIncrement();
1505+
}
1506+
1507+
}
1508+
1509+
}
1510+
14781511
static class ExitStatusException extends RuntimeException
14791512
implements ExitCodeGenerator {
14801513

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2012-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package sample.actuator;
18+
19+
import org.junit.Test;
20+
import org.junit.runner.RunWith;
21+
22+
import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort;
23+
import org.springframework.boot.test.context.SpringBootTest;
24+
import org.springframework.boot.test.web.client.TestRestTemplate;
25+
import org.springframework.http.HttpStatus;
26+
import org.springframework.http.ResponseEntity;
27+
import org.springframework.test.context.junit4.SpringRunner;
28+
29+
import static org.assertj.core.api.Assertions.assertThat;
30+
31+
/**
32+
* Integration tests for separate management and main service ports when
33+
* lazy-initialization is enabled.
34+
*
35+
* @author Madhura Bhave
36+
*/
37+
@RunWith(SpringRunner.class)
38+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
39+
"management.server.port=0", "spring.main.lazy-initialization=true" })
40+
public class ManagementPortWithLazyInitializationTests {
41+
42+
@LocalManagementPort
43+
private int managementPort;
44+
45+
@Test
46+
public void testHealth() {
47+
ResponseEntity<String> entity = new TestRestTemplate()
48+
.withBasicAuth("user", "password").getForEntity(
49+
"http://localhost:" + this.managementPort + "/actuator/health",
50+
String.class);
51+
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
52+
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
53+
}
54+
55+
}

0 commit comments

Comments
 (0)