2017-02-16 50 views
9

tleSkojarzenie między: SpringIocContainer | ApplicationContext | WebApplicationContext

Po przeczytaniu z 123456 Linki dotarłem następujące conclusion-

jak wiosny MVC zaprojektowany przez standered servlets i ułatwiać samą funkcjonalność servlet context i application context .W wiosną istnieje dwa rodzaje kontekstów ApplicationContext i WebApplicationContext -

ApplicationContext Inicjowanie przez ContextLoaderListener, jedno wystąpienie na aplikację. WebApplicationContext załadowany przez za DispatcherServlet.

Możemy zrozumieć, jak ten powyżej ApplicationContext biegnie przez WebApplicationContext więc co kiedykolwiek rzeczy związane z ApplicationContext w końcu jest to część WebApplicationContext.

Wątpliwości

  1. ApplicationContextAware ofert, które context przedmiot.

    public class SomeThing implements ApplicationContextAware{ 
    @Override 
    public void setApplicationContext(ApplicationContext ctx) throws BeanException{ 
    //this context object is `ApplicationContext` or `WebApplicationContext`? 
    } 
    } 
    
  2. context i container wydaje synonimy dla większości z nas, chcę dać example.Let że mamy dwa dyspozytora serwletu jeden dla rest i inne dla mvc.

    Pierwszy Dyspozytor -

    public class RestInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 
        @Override 
        protected String[] getServletMappings() { 
         return new String[] { "/rest/*" }; 
        } 
    } 
    

    drugie Dyspozytor -

    public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 
         @Override 
         protected String[] getServletMappings() { 
          return new String[] { "/mvc/*" }; 
         } 
        } 
    

    niż tutaj jest tylko jeden przypadek WebApplicationContext ci, wspólną częścią jest ładowany przez ContextLoaderListner jak definiować w rootContext .

    Nie jestem pewien, ale nie może być 2 IocContainer w jednym SpringApplication.

  3. BeanFactory tj SpringIocContainer jest, gdzie wszystkie obiekty fasola życie, jakie kiedykolwiek obiektów, które kojarzy się z WebApplicationContext jest część wiosennego pojemnika, jak to pojemnik zainicjowane przez WebApplicationContext? Chcę chcą wiedzieć, w jaki sposób oba są powiązane ze sobą?

    I kiedy zrobiliśmy ctx.getBean() - ten obiekt zwraca z kontenera wiosna , w jaki sposób odbywa się ta komunikacja między kontekstem a kontenerem ?

Jest podobny answer że zaprzecza oba są takie same, to mówi

Wiosna przychodzi z kilku wdrożeń kontenerowych, obie definicje fasoli obciążenia drutu fasola razem i dozować fasolę na żądanie, ale ApplicationContext oferuje znacznie więcej.

Tak więc chodzi mi o to, dlaczego obie definicje fasoli ładunkowej, fasola z drutu razem, to jest rodzaj przeróbki?

Jeszcze jedno chociaż web-app jest wiosna napędzane czy nie, musi istnieć kontekst który standard servlet zapewnia i wykorzystywane w komunikacji HTTP ......

Wiosna Wynika to czy wiosna obsługuje to w inny manner.And wiosną context oznacza tylko IOC container, których pewna część jest obciążona DispacherServlet niektóre części jest ładowany przez ContextLoaderListner i może ułatwiać znacznie więcej, tak jak I18N, access to static resource itp ..

+1

"WebApplicationContext" to "ApplicationContext". Zarówno 'ContextLoaderLIstener' i' DispatcherServlet' ładują instancję 'WebApplicationContext' (która faktycznie jest interfejsem). Istnieje tylko "ApplicationContext", niezależnie od tego, czy jest on powiązany z siecią czy nie. "ApplicationContext" jest kontenerem. –

+2

@ M.Deinum Jak zauważyłeś, istnieje jeden "kontekst" na aplikację, istnieje wiele białych dokumentów, które wyjaśniły istnienie obu, niektóre z nich zostały wymienione w pytaniu. Co więcej, jeśli zainicjalizujesz swój kontekst przez 'DispatcherServlet', tzn. Nie 'ContextLoaderListner' i wywołaj zabezpieczenie sprężyny' "spowoduje to' IllegalStateException: No ApplicationContext found: ' –

+1

Nie nigdzie nie wskazałem, że istnieje jeden kontekst ... Ale tylko wiosna ma pojęcie "ApplicationContext". Które może być typu 'WebApplicationContext'. Może być 1 lub 100. Co mi zasugerował, że zarówno 'ContextLoaderListener' i' DispatcherServlet' ładują 'WebApplicationContext'. "ContextLoaderLIstener" ładuje kontekst nazywany ogólnie kontekstem głównym, do którego również mają dostęp filtry. Możesz także zrobić to (jeśli masz jeden 'DispatcherServlet', który ujawni ten kontekst jako główny (i na ogół to, co ludzie zapominają, prowadząc do problemu, na który wskażecie)). –

Odpowiedz

0

Zasadniczo w sprężynie Aplikacja MVC konteksty sprężyn są rejestrowane w th kontekst serwletu aplikacji internetowej. Możesz to zrobić w ustawieniu plikulub w konfiguracji Java. W komentarzach wskazałem ten link, gdzie opisano, w jaki odbywa się to za pośrednictwem klas konfiguracji Java:

spring: where does `@autowired` look for beans?

Można tam zobaczyć, jak „gra” jest wykonywana. Następnie zwrócił się Pan w komentarzach co ten osiąga:

WebApplicationContextUtils.getWebApplicationContext(myServle‌​t.getServletContext(‌​)) 

Jeśli zaznaczysz kod tej klasy można zobaczyć to dostaje WebApplicationContext z atrybutami ServletContext. Atrybuty te są ustawione podczas inicjowania aplikacji WWW. Jeśli zauważysz w klasie ContextLoader (rodzica ContextLoaderListener), w metodzie initWebApplicationContext ustawia to te atrybuty do kontekstu serwletu:

/** 
    * Initialize Spring's web application context for the given servlet context, 
    * using the application context provided at construction time, or creating a new one 
    * according to the "{@link #CONTEXT_CLASS_PARAM contextClass}" and 
    * "{@link #CONFIG_LOCATION_PARAM contextConfigLocation}" context-params. 
    * @param servletContext current servlet context 
    * @return the new WebApplicationContext 
    * @see #ContextLoader(WebApplicationContext) 
    * @see #CONTEXT_CLASS_PARAM 
    * @see #CONFIG_LOCATION_PARAM 
    */ 
    public WebApplicationContext initWebApplicationContext(ServletContext servletContext) { 
     if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) { 
      throw new IllegalStateException(
        "Cannot initialize context because there is already a root application context present - " + 
        "check whether you have multiple ContextLoader* definitions in your web.xml!"); 
     } 

     Log logger = LogFactory.getLog(ContextLoader.class); 
     servletContext.log("Initializing Spring root WebApplicationContext"); 
     if (logger.isInfoEnabled()) { 
      logger.info("Root WebApplicationContext: initialization started"); 
     } 
     long startTime = System.currentTimeMillis(); 

     try { 
      // Store context in local instance variable, to guarantee that 
      // it is available on ServletContext shutdown. 
      if (this.context == null) { 
       this.context = createWebApplicationContext(servletContext); 
      } 
      if (this.context instanceof ConfigurableWebApplicationContext) { 
       ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context; 
       if (!cwac.isActive()) { 
        // The context has not yet been refreshed -> provide services such as 
        // setting the parent context, setting the application context id, etc 
        if (cwac.getParent() == null) { 
         // The context instance was injected without an explicit parent -> 
         // determine parent for root web application context, if any. 
         ApplicationContext parent = loadParentContext(servletContext); 
         cwac.setParent(parent); 
        } 
        configureAndRefreshWebApplicationContext(cwac, servletContext); 
       } 
      } 
      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); 

      ClassLoader ccl = Thread.currentThread().getContextClassLoader(); 
      if (ccl == ContextLoader.class.getClassLoader()) { 
       currentContext = this.context; 
      } 
      else if (ccl != null) { 
       currentContextPerThread.put(ccl, this.context); 
      } 

      if (logger.isDebugEnabled()) { 
       logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" + 
         WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]"); 
      } 
      if (logger.isInfoEnabled()) { 
       long elapsedTime = System.currentTimeMillis() - startTime; 
       logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms"); 
      } 

      return this.context; 
     } 
     catch (RuntimeException ex) { 
      logger.error("Context initialization failed", ex); 
      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex); 
      throw ex; 
     } 
     catch (Error err) { 
      logger.error("Context initialization failed", err); 
      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err); 
      throw err; 
     } 
    } 

Odbywa się to w tym wierszu:

servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); 

jak ty widać, jest on przechowywany w tym samym miejscu, w którym starają się go z WebApplicationContextUtils.getWebApplicationContext(myServle‌​t.getServletContext(‌​)):

/** 
    * Find the root {@code WebApplicationContext} for this web app, typically 
    * loaded via {@link org.springframework.web.context.ContextLoaderListener}. 
    * <p>Will rethrow an exception that happened on root context startup, 
    * to differentiate between a failed context startup and no context at all. 
    * @param sc ServletContext to find the web application context for 
    * @return the root WebApplicationContext for this web app, or {@code null} if none 
    * @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 
    */ 
    public static WebApplicationContext getWebApplicationContext(ServletContext sc) { 
     return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); 
    } 

Więc jak widać wszystko odpowiedzi na twoje wątpliwości znajdują się w kodzie, który wykonuje wiosną podczas uruchamiania aplikacji internetowej.

Mam nadzieję, że odpowiedziałem na twoje pytanie.

0

Do Doubt 1

w zastosowaniu sprężyny jest pojedynczy przypadek kontekście, który jest WebAplicationCntext za DispatcherServlet.Który może być patrz przez super interfejs ApplicationContext -

public class SomeThing implements ApplicationContextAware{ 
@Override 
public void setApplicationContext(ApplicationContext ctx) throws BeanException{ 
//this context object is `WebApplicationContext` which is refer by `ApplicationContext`. 
} 
} 

Wiosną kontekst oznacza tylko MKOl pojemnika, z których pewna część jest ładowany przez DispacherServlet i jakaś część jest ładowany przez ContextLoaderListner i może ułatwić wiele więcej takich jak I18N, dostęp do statycznego zasobu itp.

Powyższe informacje są prawie poprawne. Wiosną Wszystkie obiekty WebApplicationContext mają pewne wspólne odniesienia, które są rootContext. Ta odpowiedź nie zawiera odpowiedzi: doubt2, doubt3 i why all context perform same task.