ApplicationContext และ WebApplicationContext แตกต่างกันใน Spring MVC แตกต่างกันอย่างไร


193

ความแตกต่างระหว่าง Application Context กับ Web Application Context คืออะไร?

ฉันทราบว่าWebApplicationContextใช้สำหรับแอปพลิเคชันที่เน้นสถาปัตยกรรม Spring MVC หรือไม่

ฉันต้องการรู้ว่าApplicationContextแอปพลิเคชั่น MVC มีประโยชน์อะไรบ้าง? และถั่วชนิดใดที่นิยามไว้ApplicationContext?


5
ฉันไม่เชื่อว่าเป็นซ้ำของstackoverflow.com/questions/3652090/…คำถามนั้นถามเกี่ยวกับเนื้อหาของweb.xmlไฟล์ คำถามนี้ถามเกี่ยวกับฤดูใบไม้ผลิบางคลาส
Raedwald

@ Raedwald นั่นไม่ใช่ความจริง คำถามอื่น ๆ ไม่ได้พูดถึงweb.xmlแต่ก็พูดคุยเกี่ยวกับการกำหนดค่าฤดูใบไม้ผลิ XML ถั่วพันธุ์ของและApplicationContext WebApplicationContextทุกคำจำกัดความถั่วในapplicationContext.xmlจะสามารถใช้ได้ในApplicationContextขณะที่ทุกคำจำกัดความถั่วในจะสามารถใช้ได้ใน*-servlet.xml WebApplicationContext
g00glen00b

คำตอบ:


228

บริบทเว็บแอปพลิเคชันขยาย Application Context ซึ่งออกแบบมาเพื่อทำงานกับjavax.servlet.ServletContextมาตรฐานเพื่อให้สามารถสื่อสารกับคอนเทนเนอร์ได้

public interface WebApplicationContext extends ApplicationContext {
    ServletContext getServletContext();
}

ถั่วอินสแตนซ์ใน WebApplicationContext จะสามารถใช้ ServletContext ได้หากใช้อินเตอร์เฟซ ServletContextAware

package org.springframework.web.context;
public interface ServletContextAware extends Aware { 
     void setServletContext(ServletContext servletContext);
}

มีหลายสิ่งที่เป็นไปได้ที่จะทำกับอินสแตนซ์ ServletContext เช่นการเข้าถึงทรัพยากร WEB-INF (xml configs และอื่น ๆ ) โดยการเรียกใช้เมธอด getResourceAsStream () โดยทั่วไปบริบทของแอปพลิเคชันทั้งหมดที่กำหนดไว้ใน web.xml ในแอปพลิเคชัน servlet Spring เป็นบริบทของ Web Application สิ่งนี้จะไปทั้งบริบทรูทเว็บแอปและบริบทแอปของเซิร์ฟเล็ต

นอกจากนี้ขึ้นอยู่กับความสามารถในบริบทของเว็บแอปพลิเคชันอาจทำให้แอปพลิเคชันของคุณทดสอบได้ยากขึ้นและคุณอาจต้องใช้คลาสMockServletContextสำหรับการทดสอบ

ความแตกต่างระหว่าง servlet และรูทบริบท สปริงอนุญาตให้คุณสร้างลำดับชั้นบริบทแอ็พพลิเคชันหลายระดับดังนั้น bean ที่ต้องการจะถูกดึงจากบริบทพาเรนต์หากไม่มีอยู่ในบริบทแอ็พพลิเคชันปัจจุบัน ในเว็บแอปเป็นค่าเริ่มต้นมีสองระดับลำดับชั้นรากและ servlet Servlet และบริบทรูตบริบท:

สิ่งนี้ช่วยให้คุณสามารถเรียกใช้บริการบางอย่างเป็น singletons สำหรับแอปพลิเคชันทั้งหมด (โดยทั่วไปจะอยู่ที่นี่และการเข้าถึงบริการฐานข้อมูลพื้นฐานของ Spring Security beans) และบริการอื่น ๆ ที่แยกจากกันใน servlet ที่สอดคล้องกัน ตัวอย่างเช่นบริบท servlet หนึ่งจะให้บริการหน้าเว็บและอื่น ๆ จะใช้บริการเว็บไร้สัญชาติ

การแยกสองระดับนี้ออกมาจากกล่องเมื่อคุณใช้คลาส servlet ฤดูใบไม้ผลิ: เพื่อกำหนดค่าบริบทของแอปพลิเคชันรูทคุณควรใช้แท็กcontext-paramใน web.xml ของคุณ

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/root-context.xml
            /WEB-INF/applicationContext-security.xml
    </param-value>
</context-param>

(บริบทแอปพลิเคชันรูทถูกสร้างขึ้นโดยContextLoaderListenerซึ่งถูกประกาศใน web.xml

<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener> 

) และแท็กservletสำหรับบริบทแอปพลิเคชัน servlet

<servlet>
   <servlet-name>myservlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>app-servlet.xml</param-value>
   </init-param>
</servlet>

โปรดทราบว่าถ้า init-param จะถูกละไว้สปริงจะใช้ myservlet-servlet.xml ในตัวอย่างนี้

ดูเพิ่มเติม: ความแตกต่างระหว่าง applicationContext.xml และ spring-servlet.xml ใน Spring Framework


2
ขอบคุณมากสำหรับคำตอบ ฉันได้ยินมาว่ามีบริบทสองประเภทที่ใช้สำหรับแอปพลิเคชันบนเว็บ หนึ่งทำหน้าที่เป็นบริบทของแอปพลิเคชันรูทที่มีการให้คำจำกัดความที่ไม่เกี่ยวข้องกับเว็บเช่นบริการการกำหนดค่า dao ฯลฯ และอื่น ๆ สำหรับการกำหนดค่าเว็บเฉพาะเช่นการแมป Handler เป็นต้นหน้าที่ก่อนหน้านี้เป็นบริบทหลักและหลังทำหน้าที่เป็นบริบทเด็ก . ฉันต้องการทราบวิธีการประกาศโครงสร้างนี้ ฉันเคยได้ยินการเรียกกลับของ ContextListener มาบ้าง แต่ฉันค่อนข้างชัดเจนเกี่ยวกับเรื่องนี้
สุมิตร Trehan

1
โครงสร้างดังกล่าวถูก hardcoded ในเครื่องมือ servlet ของสปริงมีอย่างน้อยสองบริบทของแอปพลิเคชันในเว็บแอปสปริงดูคำตอบที่อัปเดตฉันหวังว่ามันจะช่วยได้
Boris Treukhov

discription ดีเลิศ .. ฉันมีข้อสงสัยบางอย่างในสถานการณ์นี้ .. ในขณะที่ฉันอยู่ในระยะเริ่มแรกฉันพบคำตอบที่เป็นประโยชน์ของคุณสำหรับการรับความรู้บางอย่าง ..
user533

"bean ที่ต้องการจะถูกดึงมาจากบริบทหลักหากไม่มีอยู่ในบริบทของแอปพลิเคชันปัจจุบัน" คุณอธิบายได้อย่างไร บริบทเว็บแอปพลิเคชันสามารถเข้าถึงถั่วในบริบทของแอปพลิเคชันรูทได้อย่างไร เชื่อมโยงไปยังตัวอย่างใด?
anir

14

ย้อนกลับไปที่วัน Servlet web.xml สามารถมีได้เพียงครั้งเดียวเท่านั้น<context-param>ดังนั้นจึงมีการสร้างวัตถุบริบทเพียงครั้งเดียวเมื่อเซิร์ฟเวอร์โหลดแอปพลิเคชันและข้อมูลในบริบทนั้นจะถูกใช้ร่วมกันระหว่างทรัพยากรทั้งหมด (เช่น: Servlets และ JSP) มันเหมือนกับมีชื่อโปรแกรมควบคุมฐานข้อมูลในบริบทซึ่งจะไม่เปลี่ยนแปลง ในทำนองเดียวกันเมื่อเราประกาศ contextConfigLocation param ใน<contex-param>Spring จะสร้างหนึ่ง Application Context object

 <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.myApp.ApplicationContext</param-value>
 </context-param>

คุณสามารถมีได้หลาย Servlets ในแอปพลิเคชัน ตัวอย่างเช่นคุณอาจต้องการจัดการ / รักษาความปลอดภัย / ร้องขอ * ในทางเดียวและ / ไม่ใช่ seucre / * ในทางอื่น สำหรับแต่ละ Servlets เหล่านี้คุณสามารถมีวัตถุบริบทซึ่งเป็น WebApplicationContext

<servlet>
    <servlet-name>SecureSpringDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>com.myapp.secure.SecureContext</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>SecureSpringDispatcher</servlet-name>
    <url-pattern>/secure/*</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>NonSecureSpringDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>com.myapp.non-secure.NonSecureContext</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>NonSecureSpringDispatcher</servlet-name>
    <url-pattern>/non-secure/*</url-patten>
</servlet-mapping>

14

คำตอบที่ยอมรับคือผ่าน แต่มีคำอธิบายอย่างเป็นทางการเกี่ยวกับเรื่องนี้:

WebApplicationContext เป็นส่วนเสริมของ ApplicationContext ธรรมดาที่มีคุณสมบัติพิเศษบางอย่างที่จำเป็นสำหรับการใช้งานเว็บ ซึ่งแตกต่างจาก ApplicationContext ปกติซึ่งสามารถแก้ไขธีม (ดูที่การใช้ธีม) และรู้ว่า Servlet เกี่ยวข้องกับ (โดยมีลิงก์ไปยัง ServletContext) WebApplicationContext ถูกผูกไว้ใน ServletContext และโดยใช้วิธีการคงที่ในคลาส RequestContextUtils คุณสามารถค้นหา WebApplicationContext ได้ตลอดเวลาหากคุณต้องการเข้าถึง

อ้างจากการอ้างอิงกรอบงานเว็บของ Spring

โดยวิธี servlet และบริบทรูทเป็นทั้ง webApplicationContext:

ลำดับชั้นบริบททั่วไปใน Spring Web MVC


คำอธิบายที่ดี
Shashank

6

ApplicationContext (รูทแอปพลิเคชันบริบท): เว็บแอปพลิเคชัน Spring MVC ทุกไฟล์มีไฟล์ applicationContext.xml ซึ่งได้รับการกำหนดค่าให้เป็นรากของการกำหนดค่าบริบท สปริงโหลดไฟล์นี้และสร้าง applicationContext สำหรับทั้งแอปพลิเคชัน ไฟล์นี้โหลดโดย ContextLoaderListener ซึ่งถูกกำหนดค่าเป็นพารามิเตอร์บริบทในไฟล์ web.xml และจะมีเพียงหนึ่ง applicationContext ต่อเว็บแอปพลิเคชัน

WebApplicationContext: WebApplicationContext เป็นบริบทของเว็บแอปพลิเคชันที่รับรู้เช่นมีข้อมูลบริบทของเซิร์ฟเล็ต แอปพลิเคชันเว็บเดียวสามารถมีหลาย WebApplicationContext และแต่ละ Dispatcher servlet (ซึ่งเป็นตัวควบคุมด้านหน้าของสถาปัตยกรรม Spring MVC) เชื่อมโยงกับ WebApplicationContext ไฟล์คอนฟิกูเรชัน webApplicationContext * -servlet.xml เป็นไฟล์เฉพาะสำหรับ DispatcherServlet และเนื่องจากเว็บแอปพลิเคชันสามารถมี servlet ของ dispatcher มากกว่าหนึ่งตัวที่ถูกตั้งค่าให้รองรับการร้องขอหลาย ๆ ไฟล์จึงอาจมีไฟล์ webApplicationContext มากกว่าหนึ่งไฟล์ต่อแอปพลิเคชันเว็บ


3

บริบทของแอปพลิเคชันเว็บที่ระบุโดยWebApplicationContextส่วนต่อประสานเป็นบริบทของแอปพลิเคชัน Spring สำหรับเว็บแอปพลิเคชัน มันมีคุณสมบัติทั้งหมดของบริบทแอปพลิเคชันสปริงปกติเนื่องจากWebApplicationContextอินเตอร์เฟสขยายApplicationContextอินเตอร์เฟสและเพิ่มวิธีสำหรับการดึงข้อมูล Servlet API มาตรฐานServletContextสำหรับเว็บแอปพลิเคชัน

นอกเหนือจากขอบเขต Spring bean มาตรฐานsingletonและprototypeมีขอบเขตเพิ่มเติมอีกสามขอบเขตที่พร้อมใช้งานในบริบทของเว็บแอ็พพลิเคชัน:

  • request- กำหนดขอบเขต bean เดียวให้กับวงจรชีวิตของคำขอ HTTP เดียว นั่นคือแต่ละคำร้องขอ HTTP มีอินสแตนซ์ของถั่วที่สร้างขึ้นจากด้านหลังของคำจำกัดความของถั่วเดียว
  • session - กำหนดขอบเขต bean เดียวให้กับวงจรชีวิตของเซสชัน HTTP
  • application - กำหนดขอบเขต bean เดียวให้กับวงจรชีวิตของ a ServletContext
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.