> Java > java지도 시간 > applicationContextAware 인터페이스의 setApplicationContext 메소드 실행 문제로 인해 Spring Bean을 가져오지 못했습니다.

applicationContextAware 인터페이스의 setApplicationContext 메소드 실행 문제로 인해 Spring Bean을 가져오지 못했습니다.

Linda Hamilton
풀어 주다: 2024-11-23 07:53:34
원래의
192명이 탐색했습니다.

이 기사에서는 최근에 귀하께서 관심을 가지실 것으로 생각되는 문제를 공유하고 싶습니다.

무엇이 문제인가요?

테스트 환경과 프로덕션 환경의 소스 코드는 동일하며 로컬 및 테스트 환경 모두 잘 실행되지만 서비스 클래스의 NPE로 실행되는 프로덕션 환경만 로드에 실패하여 새로운 요구 사항이 추가되었습니다. 이 클래스는 Customize 패키지(자체 개발 툴킷)의 인터페이스를 상속합니다.

프로젝트 구조

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

Customize의 디자인은 Spring을 사용하여 API와 서비스를 관리합니다. Spring 자동 스캐닝을 사용하면 클래스를 초기화할 때 ApiEnhancer 및 ServiceEnhancer의 공통 클래스가 로드되고 ApplicationContext에 의해 인스턴스를 얻습니다. 디버깅 결과 로드 시 ApplicationContext가 null이고 아직 초기화되지 않은 것으로 나타났습니다. ApplicationContextAware를 구현하여 setApplicationContext 메소드에서 초기화되므로 setApplicationContext 메소드가 실행되지 않은 것으로 추측된다.

ApplicationContextProvider 클래스를 로드하는 동안 초기화 단계에서 정적 메서드가 메서드 영역에 로드됩니다. 그러나 Bean의 인스턴스를 가져오기 위해 ApplicationContext를 사용할 때 정적 메소드는 클래스 이름으로 직접 호출됩니다. ApplicationContextProvider가 힙에 메모리를 할당하고 인스턴스화하기 전에 API가 생성되는 한 setApplicationContext 메소드는 초기화를 위해 호출되지 않습니다.

applicationContextProvider는 @Component 주석을 사용하고 Api는 @RestController 주석을 사용하며 두 클래스는 동일한 경로에 있습니다. 그러나 Spring이 이를 스캔하고 로드할 때 특정 순서가 없습니다. 이는 두 클래스 각각이 다른 클래스보다 먼저 생성될 수 있음을 의미합니다. 프로덕션 환경에서는 Api가 applicationContextProvider보다 먼저 생성되므로 Bean을 얻기 위해 클래스 이름으로 정적 메서드를 직접 호출할 때 applicationContext가 초기화되지 않습니다

.

해결책

ApplicationContextAware 인터페이스 구현 클래스의 setApplicationContext 메소드가 실행되지 않은 경우 먼저 구현 클래스가 지연 로딩으로 설정되어 있는지, 프로젝트가 전역 지연 로딩으로 구성되어 있는지 확인하세요.

이 프로젝트에서는 ApiEnhancer 및 ApplicationContextAware 인터페이스의 구현 클래스 생성 순서로 인해 문제가 발생했으며 Api 클래스는 비즈니스 로직을 처리하고 프론트에서 호출할 때 로드할 수 있는 일반 RESTful API일 뿐입니다. 끝 페이지. 따라서 지연 로딩으로 변경하면 문제가 해결되었습니다.

로딩 순서 측면에서 클래스 간의 종속 관계를 최소화하는 것이 좋습니다. 불가피한 경우 지연 로딩이나 @DependsOn, @Order, @Priority와 같은 주석을 사용하여 Bean의 로딩 순서를 제어할 수 있습니다.


프로덕션 환경과 테스트 환경 생성 순서는 왜 다른가요?

Spring의 스캐닝 프로세스를 확인하기 위해 디버그해 보겠습니다.

ClassPathBeanDeterminationScanner의 스캔 방법부터 시작합니다.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

doScan 방법

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

ClassPathScanningCandidateComponentProvider의 scanCandidateComponents 메서드

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

PathMatchingResourcePatternResolver의 findAllClassPathResources 메서드

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

doFindPathMatchingJarResources 메소드

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

JarFile은 Java 표준 라이브러리의 java.util.jar 패키지에 있는 클래스로, ZipFile을 상속하고 확장합니다. jarFile.entries()는 JarEntryIterator라는 반복자를 반환합니다.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

JarExitIterator는 JarFile의 상위 클래스 항목을 반복하는 반복자 패턴을 구현한 것입니다.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

ZipFile의 항목 메소드는 ZipExitIterator라는 반복자를 반환합니다.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

ZipExitIterator의 nextElement 메소드는 next 메소드를 호출하고, 이 메소드는 getNextEntry 메소드를 호출합니다.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

getNextEntry는 네이티브 메소드입니다.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

네이티브 메소드는 Java가 아닌 언어로 구현되고 Java Virtual Machine 내에서 호출되어 환경(운영 체제 또는 JDK 버전)에 따라 달라질 수 있는 기본 기능을 구현합니다. JAR 패키지 자체에는 순서가 없으므로 실제 순회 순서는 다양한 JAR 패키징 도구 및 환경에 따라 달라질 수 있습니다.

위 내용은 applicationContextAware 인터페이스의 setApplicationContext 메소드 실행 문제로 인해 Spring Bean을 가져오지 못했습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿