Ответ 1
Начиная с версии 4.1 RC2 эта ошибка исправлена, и вы можете выполнить ленивую загрузку при сканировании компонентов с помощью:
@ComponentScan(basePackages = ["..."], lazyInit = true)
Я использую конфигурацию на 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>
, чтобы делать то, что я хочу (хотя я не тестировал это).
Начиная с версии 4.1 RC2 эта ошибка исправлена, и вы можете выполнить ленивую загрузку при сканировании компонентов с помощью:
@ComponentScan(basePackages = ["..."], lazyInit = true)
Как вы сказали ранее, нет прямого способа справиться с этим (используя @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 для каждого класса, который вы хотите использовать, поэтому это не хорошо, если у вас много тонких классов, но полезно минимизировать доступность классов вашего другого проекта (возможно, не все ваши классы необходимы).
Надеюсь, это поможет.
В Spring Boot 2.2 вы можете установить для свойства значение true
(по умолчанию false
), чтобы включить отложенную инициализацию:
spring.main.lazy-initialization=true