diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/EagerLoadingBeanDefinitionPredicate.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/EagerLoadingBeanDefinitionPredicate.java deleted file mode 100644 index fd9c5706d87..00000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/EagerLoadingBeanDefinitionPredicate.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot; - -import java.util.function.Predicate; - -/** - * This predicate can be implemented by downstream projects to customize the behavior of - * the {@link LazyInitializationBeanFactoryPostProcessor}. - * - *
- * There are edge cases (such as in DSLs that dynamically create additional beans) in - * which it is not easy to explicitly exclude a class from the lazy-loading behavior. - * Adding an instance of this predicate to the application context can be used for these - * edge cases. - *
- * Returning "true" from this predicate will exclude a class from the lazy-loading - * process. - * - *
- * Example: - *
- *
- * {@code
- *
- * @Bean
- * public static EagerLoadingBeanDefinitionPredicate eagerLoadingBeanDefinitionPredicate() {
- * return IntegrationFlow.class::isAssignableFrom;
- * }}
- *
- * WARNING: Beans of this type will be instantiated very early in the spring application
- * life cycle.
- *
- * @author Tyler Van Gorder
- * @since 2.2.0
- */
-public interface EagerLoadingBeanDefinitionPredicate extends Predicate- * This processor will not touch a bean definition that has already had its "lazy" flag - * explicitly set to "false". - * - *
- * There are edge cases in which it is not easy to explicitly set the "lazy" flag to - * "false" (such as in DSLs that dynamically create additional beans) and therefore this - * class uses a customizer strategy that allows downstream projects to contribute - * predicates which impact if a class is considered for lazy-loading. - * - *
- * Because this is a BeanFactoryPostProcessor, this class does not use dependency
- * injection to collect the customizers. The post processor actually makes two passes
- * through the bean definitions; the first is used to find and instantiate any
- * {@link org.springframework.boot.EagerLoadingBeanDefinitionPredicate} and the second
- * pass is where bean definitions are marked as lazy.
+ * {@link BeanFactoryPostProcessor} to set lazy-init on bean definitions that not
+ * {@link LazyInitializationExcludeFilter excluded} and have not already had a value
+ * explicitly set.
*
* @author Andy Wilkinson
* @author Madhura Bhave
* @author Tyler Van Gorder
+ * @author Phillip Webb
* @since 2.2.0
+ * @see LazyInitializationExcludeFilter
*/
public final class LazyInitializationBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
-
- List
+ * Primarily intended to allow downstream projects to deal with edge-cases in which it is
+ * not easy to support lazy-loading (such as in DSLs that dynamically create additional
+ * beans). Adding an instance of this filter to the application context can be used for
+ * these edge cases.
+ *
+ * A typical example would be something like this:
+ *
+ *
+ * NOTE: Beans of this type will be instantiated very early in the spring application
+ * lifecycle so should generally be declared static and not have any dependencies.
+ *
+ * @author Tyler Van Gorder
+ * @author Philip Webb
+ * @since 2.2.0
+ */
+@FunctionalInterface
+public interface LazyInitializationExcludeFilter {
+
+ /**
+ * Returns {@code true} if the specified bean definition should be excluded from
+ * having {@code lazy-int} automatically set.
+ * @param beanName the bean name
+ * @param beanDefinition the bean definition
+ * @param beanType the bean type
+ * @return {@code true} if {@code lazy-int} should not be automatically set
+ */
+ boolean isExcluded(String beanName, BeanDefinition beanDefinition, Class> beanType);
+
+ /**
+ * Factory method that creates a filter for the given bean types.
+ * @param types the filtered types
+ * @return a new filter instance
+ */
+ static LazyInitializationExcludeFilter forBeanTypes(Class>... types) {
+ return (beanName, beanDefinition, beanType) -> {
+ for (Class> type : types) {
+ if (type.isAssignableFrom(beanType)) {
+ return true;
+ }
+ }
+ return false;
+ };
+ }
+
+}
diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/LazyInitializationExcludeFilterTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/LazyInitializationExcludeFilterTests.java
new file mode 100644
index 00000000000..5e8debf0248
--- /dev/null
+++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/LazyInitializationExcludeFilterTests.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012-2019 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot;
+
+import org.junit.jupiter.api.Test;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests for {@link LazyInitializationExcludeFilter}.
+ *
+ * @author Phillip Webb
+ */
+class LazyInitializationExcludeFilterTests {
+
+ @Test
+ void forBeanTypesMatchesTypes() {
+ LazyInitializationExcludeFilter filter = LazyInitializationExcludeFilter.forBeanTypes(CharSequence.class,
+ Number.class);
+ String beanName = "test";
+ BeanDefinition beanDefinition = mock(BeanDefinition.class);
+ assertThat(filter.isExcluded(beanName, beanDefinition, CharSequence.class)).isTrue();
+ assertThat(filter.isExcluded(beanName, beanDefinition, String.class)).isTrue();
+ assertThat(filter.isExcluded(beanName, beanDefinition, StringBuilder.class)).isTrue();
+ assertThat(filter.isExcluded(beanName, beanDefinition, Number.class)).isTrue();
+ assertThat(filter.isExcluded(beanName, beanDefinition, Long.class)).isTrue();
+ assertThat(filter.isExcluded(beanName, beanDefinition, Boolean.class)).isFalse();
+ }
+
+}
diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java
index 63d9b4087b7..a90c97f64f5 100644
--- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java
+++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java
@@ -1107,15 +1107,15 @@ class SpringApplicationTests {
}
@Test
- void lazyInitializationShouldNotApplyToBeansThatAreExplicitlyNotLazy() {
+ void lazyInitializationIgnoresBeansThatAreExplicitlyNotLazy() {
assertThat(new SpringApplication(NotLazyInitializationConfig.class)
.run("--spring.main.web-application-type=none", "--spring.main.lazy-initialization=true")
.getBean(AtomicInteger.class)).hasValue(1);
}
@Test
- void lazyInitializationShouldNotApplyToBeansThatMatchPredicate() {
- assertThat(new SpringApplication(NotLazyInitializationPredicateConfig.class)
+ void lazyInitializationIgnoresLazyInitializationExcludeFilteredBeans() {
+ assertThat(new SpringApplication(LazyInitializationExcludeFilterConfig.class)
.run("--spring.main.web-application-type=none", "--spring.main.lazy-initialization=true")
.getBean(AtomicInteger.class)).hasValue(1);
}
@@ -1430,7 +1430,7 @@ class SpringApplicationTests {
}
@Configuration(proxyBeanMethods = false)
- static class NotLazyInitializationPredicateConfig {
+ static class LazyInitializationExcludeFilterConfig {
@Bean
AtomicInteger counter() {
@@ -1443,16 +1443,16 @@ class SpringApplicationTests {
}
@Bean
- static EagerLoadingBeanDefinitionPredicate eagerLoadingBeanDefinitionPredicate() {
- return NotLazyBean.class::isAssignableFrom;
+ static LazyInitializationExcludeFilter lazyInitializationExcludeFilter() {
+ return LazyInitializationExcludeFilter.forBeanTypes(NotLazyBean.class);
}
- static class NotLazyBean {
+ }
- NotLazyBean(AtomicInteger counter) {
- counter.getAndIncrement();
- }
+ static class NotLazyBean {
+ NotLazyBean(AtomicInteger counter) {
+ counter.getAndIncrement();
}
}
+ *
+ * @Bean
+ * public static LazyInitializationExcludeFilter integrationLazyInitializationExcludeFilter() {
+ * return LazyInitializationExcludeFilter.forBeanTypes(IntegrationFlow.class);
+ * }