Подтвердить что ты не робот

Как загрузить все beans лениво с помощью @ComponentScan в Spring?

Я использую конфигурацию на Java для настройки моего контекста приложения Spring следующим образом:

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

Beans, явно определенные в конфиге, загружаются лениво, как и следовало ожидать. Однако сканированные классы, аннотированные с помощью @Named, всегда загружаются с нетерпением. Как я могу это решить?

Любая помощь приветствуется.


Обратите внимание, что для классов в пакете MyProject я могу обойти это, аннотируя их с помощью @Lazy. Но другой проект не имеет зависимости от Spring, и я хочу сохранить его таким образом (отсюда @Named, а не @Component).


Обратите внимание также, что это не является проблемой, связанной с конфигурацией на основе XML. Там, устанавливая default-lazy-init="true" в тегах <beans>, чтобы делать то, что я хочу (хотя я не тестировал это).

4b9b3361

Ответ 1

Начиная с версии 4.1 RC2 эта ошибка исправлена, и вы можете выполнить ленивую загрузку при сканировании компонентов с помощью:

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

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

Ответ 2

Как вы сказали ранее, нет прямого способа справиться с этим (используя @Lazy в классе конфигурации). Но вы можете попробовать с этим подходом:

Я полагаю, что OtherProject - это проект, который не использует Spring, и представьте, что эти классы не аннотируются.

Затем вы должны определить в 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
    }
}

Используя это, bean "lazyBean" будет создан, когда какой-то экземпляр введет его или когда вы его вызовите, но никогда не в init time.

Обратите внимание, что вам нужно определить новый bean для каждого класса, который вы хотите использовать, поэтому это не хорошо, если у вас много тонких классов, но полезно минимизировать доступность классов вашего другого проекта (возможно, не все ваши классы необходимы).

Надеюсь, это поможет.

Ответ 3

В Spring Boot 2.2 вы можете установить для свойства значение true (по умолчанию false), чтобы включить отложенную инициализацию:

spring.main.lazy-initialization=true