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

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:

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

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

@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.

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).

I hope this helps.


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

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

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


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

spring.main.lazy-initialization=true