Spring:在运行时检测懒惰的bean

时间:2018-01-18 18:39:57

标签: java spring spring-boot spring-bean

是否有任何方法可以检测到一个bean是否已经被懒惰地初始化,并且可以在上下文中对每个 bean进行可靠的工作?

特别是像这样的bean:

@Configuration
class MyConfig() {

@Bean
@Lazy
Foo foo() {
  return new Foo();
}

我找不到任何方法以编程方式检测'foo'是否很懒。

其他类型的懒豆,例如:

@Lazy
@Component
class Bar {
  ...
}

可以通过以下方式检测到:

boolean isLazy = applicationContext.findAnnotationOnBean(beanName, Lazy.class) != null

这不可靠,它可能会产生误报,例如,如果Bar bean是一个急切地初始化它的配置的一部分。

1 个答案:

答案 0 :(得分:2)

如果使用延迟初始化初始化后续bean,则可以使用ConfigurableListableBeanFactory.getBeanDefinition(String name)获取BeanDefinition实例并调用BeanDefinition.isLazyInit()以获取信息。它适用于您描述的两种情况 - 在类和bean工厂方法上使用@Lazy时。看一下以下示例,加载打印出懒惰加载的所有bean:

import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;

@SpringBootApplication
public class Application {

    @Bean
    @Lazy
    public Foo foo() {
        return new Foo();
    }

    public static void main(String[] args) {
        final ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);

        ctx.getBeanFactory().getBeanNamesIterator().forEachRemaining(bean -> {
            try {
                final BeanDefinition beanDefinition = ctx.getBeanFactory().getBeanDefinition(bean);
                if (beanDefinition.isLazyInit()) {
                    System.out.println("Bean '" + bean + "' is lazy initialized...");
                }
            } catch (NoSuchBeanDefinitionException e) {}
        });
    }

    static class Foo {
        private boolean bar = true;
    }
}

当我运行它时,我在控制台中看到以下部分:

Bean 'otherLazyBean' is lazy initialized...
Bean 'foo' is lazy initialized...
Bean 'mvcHandlerMappingIntrospector' is lazy initialized...

otherLazyBean是使用@Lazy注释注释的组件类。希望它有所帮助。