>  기사  >  Java  >  springboot 애플리케이션 서비스 시작 이벤트 모니터링을 구현하는 방법

springboot 애플리케이션 서비스 시작 이벤트 모니터링을 구현하는 방법

WBOY
WBOY앞으로
2023-05-16 23:10:372125검색

    1. 소개

    Spring Boot는 애플리케이션 시작 시 특별한 처리를 수행하는 데 사용되는 CommandLineRunner와 ApplicationRunner의 두 가지 인터페이스를 제공합니다. 이 코드는 SpringApplication의 run() 메서드가 완료되기 전에 실행됩니다. 이전 장에서 소개한 Spring의 ApplicationListener 인터페이스 사용자 정의 리스너 및 Servlet의 ServletContextListener 리스너와 비교합니다. 두 가지를 모두 사용하면 애플리케이션 시작 매개변수를 쉽게 사용할 수 있고 다양한 매개변수를 기반으로 다양한 초기화 작업을 수행할 수 있다는 장점이 있습니다.

    2. 일반 시나리오 소개

    CommandLineRunner 및 ApplicationRunner 인터페이스를 구현합니다. 일반적으로 다음과 같이 애플리케이션이 시작되기 전에 특수 코드 실행에 사용됩니다.

    • 일반적으로 사용되는 시스템 데이터를 메모리에 로드

    • 마지막 애플리케이션 실행에서 정크 데이터 정리

    • 시스템 시작 후 알림 보내기

    아래 그림과 같이 CommandLineRunner 인터페이스를 구현하고 애플리케이션이 시작될 때 일반적으로 사용되는 구성 데이터를 시스템에 로드했습니다. 데이터베이스에서 메모리로 로드합니다. 나중에 데이터를 사용할 때는 getSysConfigList 메소드만 호출하면 됩니다. 매번 데이터베이스에 데이터를 로드할 필요가 없습니다. 시스템 리소스를 절약하고 데이터 로딩 시간을 줄입니다.

    springboot 애플리케이션 서비스 시작 이벤트 모니터링을 구현하는 방법

    2. @Component 정의 메소드를 통해 간단한 코드 실험을 구현합니다.

    CommandLineRunner: 매개변수가 문자열 배열입니다.

    @Slf4j
    @Component
    public class CommandLineStartupRunner implements CommandLineRunner {
        @Override
        public void run(String... args){
            log.info("CommandLineRunner传入参数:{}", Arrays.toString(args));
        }
    }

    ApplicationRunner: 매개변수를 ApplicationArguments에 넣고 getOptionNames(), getOptionValues를 통해 매개변수를 가져옵니다. () 및 getSourceArgs()

    @Slf4j
    @Component
    public class AppStartupRunner implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments args)  {
            log.info("ApplicationRunner参数名称: {}", args.getOptionNames());
            log.info("ApplicationRunner参数值: {}", args.getOptionValues("age"));
            log.info("ApplicationRunner参数: {}", Arrays.toString(args.getSourceArgs()));
        }
    }

    @Bean 정의 메소드를 통해 달성됨

    이 메소드는 실행 순서를 지정할 수 있습니다. 처음 두 Bean은 CommandLineRunner이고 마지막 Bean은 ApplicationRunner입니다.

    @Configuration
    public class BeanRunner {
        @Bean
        @Order(1)
        public CommandLineRunner runner1(){
            return new CommandLineRunner() {
                @Override
                public void run(String... args){
                    System.out.println("BeanCommandLineRunner run1()" + Arrays.toString(args));
                }
            };
        }
    
        @Bean
        @Order(2)
        public CommandLineRunner runner2(){
            return new CommandLineRunner() {
                @Override
                public void run(String... args){
                    System.out.println("BeanCommandLineRunner run2()" + Arrays.toString(args));
                }
            };
        }
    
        @Bean
        @Order(3)
        public ApplicationRunner runner3(){
            return new ApplicationRunner() {
                @Override
                public void run(ApplicationArguments args){
                    System.out.println("BeanApplicationRunner run3()" + Arrays.toString(args.getSourceArgs()));
                }
            };
        }
    }

    @Order를 통해 실행 순서를 설정할 수 있습니다

    3. 테스트를 실행합니다

    다음 매개변수를 IDEA Springboot 시작 구성에 추가하고 애플리케이션을 저장하고 시작합니다

    springboot 애플리케이션 서비스 시작 이벤트 모니터링을 구현하는 방법

    테스트 출력 결과:

    c.z. boot.launch.config .AppStartupRunner : ApplicationRunner 매개변수 이름: [이름, 나이]
    c.z.boot.launch.config.AppStartupRunner : ApplicationRunner 매개변수 값: [18]
    c.z.boot.launch.config.AppStartupRunner : ApplicationRunner 매개변수: [-- name=zimug, - -age=18]

    BeanApplicationRunner run3()[--name=zimug, --age=18]

    c.z.b.l.config.CommandLineStartupRunner : CommandLineRunner 수신 매개변수: [--name=zimug, --age =18]
    BeanCommandLineRunner run1()[--name=zimug, --age=18]
    e=18]
    BeanCommandLineRunner run2()[--name=zimug, --age=18]

    많은 테스트 끝에 , 저자는 테스트 결과 이 ​​우선순위가 항상 이랬으나 현재는 이것이 표준인지 여부가 불분명합니다. Runner 인터페이스를 구현하는 방법

    • Order. 주석은 동일한 CommandLineRunner 또는 ApplicationRunner의 실행 순서만 보장할 수 있으며 클래스 간 순서는 보장할 수 없습니다

    • 4. 요약

    • CommandLineRunner 및 ApplicationRunner의 핵심 사용법은 일관됩니다. 즉, 특수 코드 실행에 사용됩니다. 응용 프로그램 시작 전. ApplicationRunner의 실행 순서는 CommandLineRunner보다 우선합니다. ApplicationRunner는 매개변수를 객체로 캡슐화하고 매개변수 이름, 매개변수 값 등을 얻는 방법을 제공하므로 작업이 더욱 편리해집니다.
    • 5. 문제 요약

    • 이것은 저자가 실제로 직면한 실제 문제입니다. 즉, CommandLineRunner의 여러 구현을 정의했습니다. 이상한 문제가 발생합니다.
    CommandLineRunner의 여러 구현을 정의하면 그 중 하나 또는 여러 개가 실행되지 않습니다.

    분석: 다음 코드는 프로젝트 시작 후 SpringBootApplication이 실행되는 코드입니다. 코드에서 순회를 통해 CommandLineRunner 또는 ApplicationRunner가 시작되는 것을 볼 수 있습니다. 즉, 동기적으로 실행되는 이전 CommandLineRunner의 실행이 완료된 후에만 다음 CommandLineRunner가 실행됩니다.

    private void callRunners(ApplicationContext context, ApplicationArguments args) {
    		List<Object> runners = new ArrayList<>();
    		runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
    		runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
    		AnnotationAwareOrderComparator.sort(runners);
    		for (Object runner : new LinkedHashSet<>(runners)) {
    			if (runner instanceof ApplicationRunner) {
    				callRunner((ApplicationRunner) runner, args);
    			}
    			if (runner instanceof CommandLineRunner) {
    				callRunner((CommandLineRunner) runner, args);
    			}
    		}
    	}

    따라서 CommandLineRunner 구현의 실행 메서드 본문에서 동기식 차단 API 또는 while(true) 루프가 호출되면 순회에서 CommandLineRunner 이후의 다른 구현은 실행되지 않습니다.

    위 내용은 springboot 애플리케이션 서비스 시작 이벤트 모니터링을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제