Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何延迟加载所有SpringBean,无论它是由SpringBoot2.2中的@Bean还是@Component定义的_Java_Spring_Spring Boot - Fatal编程技术网

Java 如何延迟加载所有SpringBean,无论它是由SpringBoot2.2中的@Bean还是@Component定义的

Java 如何延迟加载所有SpringBean,无论它是由SpringBoot2.2中的@Bean还是@Component定义的,java,spring,spring-boot,Java,Spring,Spring Boot,我正在编写一个spring应用程序,它是交互式的,基本上可以处理很多命令,比如创建、列出、更新、删除各种类型的资源 现在,只要假设应用程序的一次运行只处理一个命令,程序就会退出 对于要验证命令的所有类,执行命令,每个资源所需的工厂类有一个单独的类,每个类都用@Component注释进行注释,以便spring管理所有组件 还有一些通过@Bean方法手动定义的Bean 现在,我的应用程序首先确定了执行哪种命令(创建、删除、列表、更新等),我希望创建该命令的唯一bean,并在需要时自动连接(从用户获取

我正在编写一个spring应用程序,它是交互式的,基本上可以处理很多命令,比如创建、列出、更新、删除各种类型的资源

现在,只要假设应用程序的一次运行只处理一个命令,程序就会退出

对于要验证命令的所有类,执行命令,每个资源所需的工厂类有一个单独的类,每个类都用
@Component
注释进行注释,以便spring管理所有组件

还有一些通过
@Bean
方法手动定义的Bean

现在,我的应用程序首先确定了执行哪种命令(创建、删除、列表、更新等),我希望创建该命令的唯一bean,并在需要时自动连接(从用户获取命令后),并且我希望避免创建几十个与其他命令相关的bean

在搜索时,我了解了spring提供的bean的惰性实例化。 然而,我不确定这是否是我正在寻找的武器

我尝试的

  • 首先我发现了@Lazy注释,但是因为我想懒洋洋地加载所有bean,所以我不想在每个类中到处写@Lazy注释
  • 然后我在application.yml中找到了下面属性的设置
我试过了,但它仍然没有懒洋洋地创建bean

我的application.yml文件如下所示

spring:
  main:
    lazy-initialization: true
我的主SpringBootApplication文件如下所示:

@Slf4j
@SpringBootApplication
public class SpringBootApplication {
    public static void main(String[] args) {
        System.out.println("Loading Application...");
        ApplicationContext context = SpringApplication.run(SpringBootApplication.class, args);



        final AtomicInteger counter = new AtomicInteger(0);
        log.info("**************** START: Total Bean Objects: {} ******************", context.getBeanDefinitionCount());

        Arrays.asList(context.getBeanDefinitionNames())
                .forEach(beanName -> {
                    log.info("{}) Bean Name: {} ", counter.incrementAndGet(), beanName);
                });

        log.info("**************** END: Total Bean: {} ******************", context.getBeanDefinitionCount());
    }
}


@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MyClass1 implements ResourceCreator<MyClass2, MyClass3> {
    private final RequestValidatorImpl requestValidator;
    private final ResourceCreator resourceCreator;

@Override
public MyClass2 toImplementFunction(MyClass3 myclass3) {
//logic
}

我的其他课程如下所示:

@Slf4j
@SpringBootApplication
public class SpringBootApplication {
    public static void main(String[] args) {
        System.out.println("Loading Application...");
        ApplicationContext context = SpringApplication.run(SpringBootApplication.class, args);



        final AtomicInteger counter = new AtomicInteger(0);
        log.info("**************** START: Total Bean Objects: {} ******************", context.getBeanDefinitionCount());

        Arrays.asList(context.getBeanDefinitionNames())
                .forEach(beanName -> {
                    log.info("{}) Bean Name: {} ", counter.incrementAndGet(), beanName);
                });

        log.info("**************** END: Total Bean: {} ******************", context.getBeanDefinitionCount());
    }
}


@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MyClass1 implements ResourceCreator<MyClass2, MyClass3> {
    private final RequestValidatorImpl requestValidator;
    private final ResourceCreator resourceCreator;

@Override
public MyClass2 toImplementFunction(MyClass3 myclass3) {
//logic
}


另外,如果您愿意,请评论我是否应该像我正在使用的那样为每个类使用@Component,以及什么是更好的做法。

我认为您误解了您正在传递的
懒惰
标志的含义, 这意味着只有在调用该对象时才会创建该对象,但它并没有说它不会扫描该包。Spring将扫描所有包并存储bean定义名称,但只有在调用它时才会创建对象,前提是您已将
lazy
标志传递给它

您可以通过检查在传递
lazy
标志时创建的bean的数量来验证此行为。 您可以按照下面的说明进行检查

ApplicationContext context = SpringApplication.run(SpringBootApplication.class, args);
System.out.println("count:"+context.getBeanDefinitionCount());
2020年4月7日开始编辑

另一种方法是创建一个构造函数,并使用该构造函数注入自动连接属性,并在它们进入构造函数时打印日志

我在一个示例项目中也做了同样的工作,下面是结果,第一个是针对急切的初始化,第二个是针对懒惰的初始化

spring.main.lazy初始化=false
应用程序日志

Inside Constructor
calling bean
inside bean method
calling bean
Inside Constructor
inside bean method
spring.main.lazy初始化=true
应用程序日志

Inside Constructor
calling bean
inside bean method
calling bean
Inside Constructor
inside bean method
2020年4月7日编辑结束

如果我回答了你的问题,请将此标记为已回答。 谢谢你

长话短说: 对于任何想要懒洋洋地初始化整个Spring引导上下文的人来说,将此属性设置为true是一种方法:

spring.main.lazy-initialization=true
专业提示: 它可以与@Lazy注释结合使用,设置为false;因此,所有定义的bean都将使用延迟初始化,除了那些我们显式配置为@lazy(false)的bean


这样,延迟初始化就变成了opt-out而不是默认的opt-In

,这正是我所期望的。如果您查看SpringbootApplication文件,我正在开始和结束时记录context.getBeanDefinitionCount(),但奇怪的是,在设置惰性标志true和false时,它是60(我的应用程序中的bean数)。。这就是我发布问题的原因。另一种检查方法是getBeanDefinition(“test”).isLazyInit()。这将告诉您application.yml中提供的配置是否被spring正确读取