Exclude infrastructure beans from lazy initialization
Closes gh-39831
This commit is contained in:
		
							parent
							
								
									e4462b0940
								
							
						
					
					
						commit
						9c68ce5900
					
				|  | @ -1,5 +1,5 @@ | ||||||
| /* | /* | ||||||
|  * Copyright 2012-2022 the original author or authors. |  * Copyright 2012-2024 the original author or authors. | ||||||
|  * |  * | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  * you may not use this file except in compliance with the License. |  * you may not use this file except in compliance with the License. | ||||||
|  | @ -37,11 +37,15 @@ import org.springframework.core.Ordered; | ||||||
|  * automatically excluded from lazy initialization to ensure that their |  * automatically excluded from lazy initialization to ensure that their | ||||||
|  * {@link SmartInitializingSingleton#afterSingletonsInstantiated() callback method} is |  * {@link SmartInitializingSingleton#afterSingletonsInstantiated() callback method} is | ||||||
|  * invoked. |  * invoked. | ||||||
|  |  * <p> | ||||||
|  |  * Beans that are in the {@link BeanDefinition#ROLE_INFRASTRUCTURE infrastructure role} | ||||||
|  |  * are automatically excluded from lazy initialization, too. | ||||||
|  * |  * | ||||||
|  * @author Andy Wilkinson |  * @author Andy Wilkinson | ||||||
|  * @author Madhura Bhave |  * @author Madhura Bhave | ||||||
|  * @author Tyler Van Gorder |  * @author Tyler Van Gorder | ||||||
|  * @author Phillip Webb |  * @author Phillip Webb | ||||||
|  |  * @author Moritz Halbritter | ||||||
|  * @since 2.2.0 |  * @since 2.2.0 | ||||||
|  * @see LazyInitializationExcludeFilter |  * @see LazyInitializationExcludeFilter | ||||||
|  */ |  */ | ||||||
|  | @ -63,6 +67,7 @@ public final class LazyInitializationBeanFactoryPostProcessor implements BeanFac | ||||||
| 		ArrayList<LazyInitializationExcludeFilter> filters = new ArrayList<>( | 		ArrayList<LazyInitializationExcludeFilter> filters = new ArrayList<>( | ||||||
| 				beanFactory.getBeansOfType(LazyInitializationExcludeFilter.class, false, false).values()); | 				beanFactory.getBeansOfType(LazyInitializationExcludeFilter.class, false, false).values()); | ||||||
| 		filters.add(LazyInitializationExcludeFilter.forBeanTypes(SmartInitializingSingleton.class)); | 		filters.add(LazyInitializationExcludeFilter.forBeanTypes(SmartInitializingSingleton.class)); | ||||||
|  | 		filters.add(new InfrastructureRoleLazyInitializationExcludeFilter()); | ||||||
| 		return filters; | 		return filters; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -105,4 +110,18 @@ public final class LazyInitializationBeanFactoryPostProcessor implements BeanFac | ||||||
| 		return Ordered.HIGHEST_PRECEDENCE; | 		return Ordered.HIGHEST_PRECEDENCE; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Excludes all {@link BeanDefinition bean definitions} which have the infrastructure | ||||||
|  | 	 * role from lazy initialization. | ||||||
|  | 	 */ | ||||||
|  | 	private static final class InfrastructureRoleLazyInitializationExcludeFilter | ||||||
|  | 			implements LazyInitializationExcludeFilter { | ||||||
|  | 
 | ||||||
|  | 		@Override | ||||||
|  | 		public boolean isExcluded(String beanName, BeanDefinition beanDefinition, Class<?> beanType) { | ||||||
|  | 			return beanDefinition.getRole() == BeanDefinition.ROLE_INFRASTRUCTURE; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /* | /* | ||||||
|  * Copyright 2012-2021 the original author or authors. |  * Copyright 2012-2024 the original author or authors. | ||||||
|  * |  * | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  * you may not use this file except in compliance with the License. |  * you may not use this file except in compliance with the License. | ||||||
|  | @ -22,6 +22,7 @@ import java.util.List; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
| 
 | 
 | ||||||
| import org.springframework.beans.factory.SmartInitializingSingleton; | import org.springframework.beans.factory.SmartInitializingSingleton; | ||||||
|  | import org.springframework.beans.factory.config.BeanDefinition; | ||||||
| import org.springframework.context.annotation.AnnotationConfigApplicationContext; | import org.springframework.context.annotation.AnnotationConfigApplicationContext; | ||||||
| 
 | 
 | ||||||
| import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  | @ -30,6 +31,7 @@ import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  * Tests for {@link LazyInitializationBeanFactoryPostProcessor}. |  * Tests for {@link LazyInitializationBeanFactoryPostProcessor}. | ||||||
|  * |  * | ||||||
|  * @author Andy Wilkinson |  * @author Andy Wilkinson | ||||||
|  |  * @author Moritz Halbritter | ||||||
|  */ |  */ | ||||||
| class LazyInitializationBeanFactoryPostProcessorTests { | class LazyInitializationBeanFactoryPostProcessorTests { | ||||||
| 
 | 
 | ||||||
|  | @ -58,6 +60,19 @@ class LazyInitializationBeanFactoryPostProcessorTests { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Test | ||||||
|  | 	void whenLazyInitializationIsEnabledThenInfrastructureRoleBeansAreInitializedDuringRefresh() { | ||||||
|  | 		try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) { | ||||||
|  | 			context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor()); | ||||||
|  | 			context.register(BeanState.class); | ||||||
|  | 			context.registerBean(ExampleBean.class, | ||||||
|  | 					(definition) -> definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE)); | ||||||
|  | 			context.refresh(); | ||||||
|  | 			BeanState beanState = context.getBean(BeanState.class); | ||||||
|  | 			assertThat(beanState.initializedBeans).containsExactly(ExampleBean.class); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	static class ExampleBean { | 	static class ExampleBean { | ||||||
| 
 | 
 | ||||||
| 		ExampleBean(BeanState beanState) { | 		ExampleBean(BeanState beanState) { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue