java 如何在Spring中使用@ComponentScan延迟加载所有bean?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12207057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 08:02:19  来源:igfitidea点击:

How to load all beans lazily with @ComponentScan in Spring?

javaspringdependency-injection

提问by rolve

I am using Java-based config to set up my Spring application context like this:

我正在使用基于 Java 的配置来设置我的 Spring 应用程序上下文,如下所示:

@Configuration
@Lazy
@ComponentScan(basePackageClasses = {MyProject.class, OtherProject.class})
public class MyAppConfig {
    ...
}

Beans defined explicitly in the config are loaded lazily, like you would expect. However, scanned classes annotated with @Namedare always loaded eagerly. How can I solve this?

像您期望的那样,在配置中明确定义的 Bean 是延迟加载的。但是,带有注释的扫描类@Named总是会急切地加载。我该如何解决这个问题?

Any help is appreciated.

任何帮助表示赞赏。



Note that for classes in the MyProjectpackage, I can work around this by annotating them with @Lazyas well. But the other project does not have a dependency to Spring and I want to keep it like that (hence @Namedand not @Component).

请注意,对于MyProject包中的类,我也可以通过对它们进行注释来解决这个问题@Lazy。但是另一个项目对 Spring 没有依赖性,我想保持这种状态(因此@Named而不是@Component)。



Note also that this does not seam to be a problem in XML-based config. There, setting default-lazy-init="true"in the <beans>tag seams to do what I want (although I haven't tested that).

另请注意,这在基于 XML 的配置中并不是一个问题。目前,设置default-lazy-init="true"<beans>标签接缝处做我想做的(虽然我没有测试过)。

回答by Eric S.

As of version 4.1 RC2, this bug is fixed, and you can accomplish lazy loading on component scan with:

从 4.1 RC2 版本开始,此错误已修复,您可以通过以下方式完成组件扫描的延迟加载:

@ComponentScan(basePackages = ["..."], lazyInit = true)

https://jira.spring.io/browse/SPR-10459

https://jira.spring.io/browse/SPR-10459

回答by sgroh

As you said before there is no direct way to handle that (using @Lazy in the configuration class). But you can try with this approach:

正如您之前所说,没有直接的方法来处理(在配置类中使用 @Lazy)。但是您可以尝试使用这种方法:

I suppose that OtherProject is a project that is not using Spring, and imagine that these classes are not annotated.

我想 OtherProject 是一个没有使用 Spring 的项目,并且想象这些类没有被注释。

Then you should define in Myproject a configuration that looks like that:

然后你应该在 Myproject 中定义一个如下所示的配置:

@Configuration
// Avoid use this line if classes aren't annotated @ComponentScan("com.otherProject")
public class MyProjectConfig {

    @Bean(name = "lazyBean")
    @Lazy
    public LazyBean lazyBean(){
        System.out.println("Loading LazyBean bean");
        return new LazyBean(); // Or use a static method factory, this is only an example
    }
}

Using this, the bean "lazyBean" will be created when some instance inject it or when you explicity call it, but never at init time.

使用它,bean "lazyBean" 将在某些实例注入它或当您显式调用它时创建,但永远不会在初始化时创建。

Please note that you need to define a new bean per class that you want to use, so this is not good if you have tons of classes but good to minimize the accessibility of classes of your other project (perhaps not all your classes are necessary).

请注意,您需要为每个要使用的类定义一个新 bean,因此如果您有大量类,这并不好,但有助于最大限度地减少其他项目的类的可访问性(也许并非所有类都是必需的) .

I hope this helps.

我希望这有帮助。

回答by davidxxx

From Spring Boot 2.2, you can set a property to true(default to false) to enable the lazy initialization :

从 Spring Boot 2.2 开始,您可以将属性设置为true(默认为false)以启用延迟初始化:

spring.main.lazy-initialization=true