복붙노트

[SPRING] 비 스프링 컨텍스트에서로드 된 스프링 빈 확인

SPRING

비 스프링 컨텍스트에서로드 된 스프링 빈 확인

나는 (저지 2.6 클래스와) 서블릿과 함께 스프링 애플리케이션을 사용한다.

저지 / 비 스프링 컨텍스트에서 Spring bean을 가져와야합니다.

비슷한 질문이 컨텍스트의 정적 래퍼에 컨텍스트를 가져 오기 위해 제안되었습니다.

public static ApplicationContext getContext() {
    return context;
}

컨텍스트가 이미로드되었는지 또는 null이 아닌지 어떻게 확인할 수 있습니까?

내가 할 수 없다면 봄 문맥이로드 될 때까지 어떻게 기다려야하나요?

간단한 HttpServlet 코드에서 저지 컨텍스트 또는 호출 빈 (bean)을 호출 할 경우

편집하다

Jersey는 jersey-spring3 종속 항아리를 사용하여 잘 작동하므로 제 질문은 Spring 컨트롤에서 Servlet에 관한 것입니다.

EDIT 2

응용 프로그램이 @entpnerd 추천 문서와 다른 스프링을로드 중입니다.

WebApplicationInitializer를 구현하는 서블릿을 등록합니다.

public class MyWebAppInitializer implements WebApplicationInitializer {

또한 web.xml에 DispatcherServlet이 구성되어 있어야합니다.

Spring이로드 된 후에 만 ​​DispatcherServlet을로드 할 수 있습니까?

init 메소드에 Autowiring 기능을 추가했기 때문에 :

WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext())
                    .getAutowireCapableBeanFactory().autowireBean(this);

요청을 처리하기 전에 시간 초과를 추가하는 것이 가장 선호되는 솔루션입니까, 아니면 처리 할 수있는 클래스 로딩을 조정할 수 있습니까?

3 수정

나는 주사에 대한 답변과 답변을 찾았지만 Spring이 Servlet보다 먼저로드되는 이유는 알지 못했습니다.

해결법

  1. ==============================

    1.실제 구현은 스프링 부트와 Jersery 초기화의 정확한 방법에 따라 다를 수 있지만 아이디어는 매우 간단합니다.

    실제 구현은 스프링 부트와 Jersery 초기화의 정확한 방법에 따라 다를 수 있지만 아이디어는 매우 간단합니다.

    아이디어:

    순전히 런타임 프레임 워크 인 스프링 부트는 모두 애플리케이션 컨텍스트 (질문 관점에서)를 적절하게로드하는 것에 관한 것입니다.

    결론적으로,로드 될 때 어딘가에 메모리에있는 애플리케이션 컨텍스트가 있으며이 애플리케이션 컨텍스트에서 Bean에 액세스 할 수 있습니다.

    이제, 저지가 스프링 / 스프링 부팅으로 구동되지 않는다고 말하면서,이 애플리케이션 컨텍스트는 저지의 정적 인 전역 변수를 통해 접근 할 수 있어야합니다. 아주 추악하지만 작동해야합니다.

    따라서 아이디어에는 두 단계가 있습니다.

    가능한 구현

    기술적으로 1 단계는 일종의 싱글 톤에서 애플리케이션 컨텍스트를 저장하는 일종의 스프링 부트 리스너를 구현하여 수행 할 수 있습니다.

    enum ApplicationContextHolder {
       INSTANCE;
        private ApplicationContext ctx;
        void setApplicationContext(ApplicationContext ctx) {
            this.ctx = ctx;
        }
    
        ApplicationContext getCtx() {
            return this.ctx;
        }
    
    }
    
    
    // and a listener (spring boot provides many ways to register one, but the 
    // implementation should be something like this):
    // The main point is that its managed by spring boot, and hence and access to 
    // the application context
    class StartupListener implements ApplicationListener<ContextRefreshedEvent> {
        @Override
        public void onApplicationEvent(ContextRefreshedEvent event) {           
                 ApplicationContextHolder
                 .INSTANCE
                 .setApplicationContext(event.getApplicationContext());
        }
    }
    

    이제 2 단계는 다음과 같습니다.

    class MyJerseyOrWhateverComponentThatWantsToAccessApplicationContext {
    
        public void foo() {
           ApplicationContext ctx = ApplicationContextHolder.INSTANCE.getCtx();
           ... 
           ctx.getBean(...);
        }
    }
    
  2. ==============================

    2.따라서이를위한 실행 가능한 솔루션은 다음 두 단계에서 발생할 수 있습니다.

    따라서이를위한 실행 가능한 솔루션은 다음 두 단계에서 발생할 수 있습니다.

    다음 코드를 예제로 생각해보십시오.

    SpringMetaBean.java

    // @Component so that it's part of the Spring context
    // Implement ApplicationContextAware so that the ApplicationContext will be loaded
    // correctly
    @Component
    public class SpringMetaBean implements ApplicationContextAware {
      private ApplicationContext appCtx;
      public setApplicationContext(ApplicationContext appCtx) {
        this.appCtx = appCtx;
      }
    
      // @PostConstruct so that when loaded into the Spring context, this method will
      // automatically execute and notify ApplicationContextHolder with a reference to
      // the ApplicationContext
      @PostConstruct
      public void setup() {
        ApplicationContextHolder.set(this.appCtx);
      }
    }
    

    ApplicationContextHolder.java

    public class ApplicationContextHolder {
      // ensure the reference is thread-safe because Spring and standalone Servlet will
      // probably be running on different threads.
      private final AtomicReference<ApplicationContext> appCtxContainer = new AtomicReference<>();
    
      public void set(ApplicationContext appCtx) {
        this.appCtxContainer.set(appCtx);
      }
    
      public ApplicationContext get() {
        return this.appCtxContainer.get();
      }
    }
    

    MyStandaloneServlet.java

    public class MyStandaloneServlet {
      // my request handler method
      public void getResponse(HttpServletRequest rq) {
        ApplicationContext springAppCtx = ApplicationContextHolder.get();
        // if not null, we know that Spring has been loaded and we can dig into the
        // application context.
      }
    }
    
  3. from https://stackoverflow.com/questions/47434743/ensure-spring-bean-loaded-from-non-spring-context by cc-by-sa and MIT license