Как Lazy загрузить все компоненты Spring, независимо от того, определено ли оно в @Bean или @Component в Springboot 2.2 - PullRequest
1 голос
/ 06 апреля 2020

Я пишу весеннее приложение, которое является интерактивным и в основном обрабатывает множество команд, таких как создание, список, обновление, удаление различных типов ресурсов.

Пока предположим, что один запуск приложения обрабатывает только одну команду, и программа завершается.

Чтобы все классы подтвердили команду, выполните команду, необходимые для каждого класса фабрики Ресурс существует отдельный класс, и каждый класс аннотируется @Component для Spring для управления всеми компонентами.

Существуют также некоторые из определяемых вручную bean-компонентов методом @Bean.

Теперь, когда мое приложение сначала определяет, какая команда выполняется (создание, удаление, список, обновление и т. Д. *) 1050 *), я хочу, чтобы единственные bean-компоненты этой команды создавались и Autowired везде, где это необходимо (после получения команды от пользователя), и я хочу избежать создания десятков bean-компонентов, связанных с другими командами.

При поиске Я узнал о Ленивом экземпляре Бобов, который предоставляет весна. Тем не менее, я не уверен, что это оружие, которое я ищу.

Что я пытался

  • Самым первым я нашел аннотацию @Lazy, но так как Я хочу лениво загрузить все Бины, я не хочу писать @Lazy везде в каждом классе.
  • Тогда я обнаружил, что настройка свойства ниже в application.yml делает работу.
spring:
  main:
    lazy-initialization: true

Я попробовал это, но все же, это не лениво создавать бины.

Мои 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
}

При запуске приложения он печатает все классы, где я аннотировал @Component, а также компоненты, созданные методом @Bean.

Я также пытался использовать ниже в Application.properties, но все еще бесполезно.

spring.main.lazy-initialization=true

Кроме того, если вы будете sh, пожалуйста, прокомментируйте, должен ли я использовать @Component для каждого класса, который я использую, или нет, и что лучше тренируйтесь вместо этого.

1 Ответ

1 голос
/ 06 апреля 2020

Я думаю, вы неправильно поняли значение флага lazy, который вы передаете. Это означает, что объект будет создан только тогда, когда он вызван, но это не говорит о том, что он не будет сканировать этот пакет. Spring просканирует все пакеты и сохранит имена определений bean-компонентов, но создаст объекты только при его вызове, если вы передали ему флаг lazy.

Это поведение можно проверить, проверив количество бины создаются, когда вы передаете флаг lazy как true и false. Вы можете проверить это, как указано ниже

ApplicationContext context = SpringApplication.run(SpringBootApplication.class, args);
System.out.println("count:"+context.getBeanDefinitionCount());

Редактировать 7 апреля 2020 г. начало

Еще один способ сделать это - создать конструктор и использовать его, чтобы ввести свойства автопроводки и распечатать Журнал, когда они входят в конструктор.

Я сделал то же самое в примере проекта и ниже он результат, первый для быстрой инициализации и следующий для ленивых.

spring.main.lazy-initialization=false Журналы приложений

Inside Constructor
calling bean
inside bean method

spring.main.lazy-initialization=true Журналы приложений

calling bean
Inside Constructor
inside bean method

Редактировать 7 апреля 2020 г., конец

Отметьте это как ответ, если я ответил на ваш вопрос. Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...