BeanFactory vs ApplicationContext


235

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

เช่นเดียวกับการออกกำลังกายฉันกำลังเขียนวิธีหลักสำหรับหนึ่งในตัวอย่าง / โครงการทดสอบของฉัน สิ่งหนึ่งที่ฉันไม่ชัดเจนเกี่ยวกับความแตกต่างที่แน่นอนระหว่างBeanFactoryและApplicationContext- ซึ่งเหมาะสมที่จะใช้ในเงื่อนไขใด

ฉันเข้าใจว่ามันApplicationContextขยายออกไปBeanFactoryแต่ถ้าฉันเพิ่งเขียนวิธีหลักอย่างง่ายฉันต้องใช้ฟังก์ชันพิเศษที่ApplicationContextให้มาหรือไม่ และมีฟังก์ชั่นพิเศษApplicationContextอะไรบ้างที่มีให้?

นอกเหนือจากการตอบ "ซึ่งฉันควรใช้ในวิธีการหลัก ()" มีมาตรฐานหรือแนวทางปฏิบัติเท่าที่ควรใช้ในสถานการณ์เช่นนี้หรือไม่? ควรเขียนเมธอด main () ของฉันให้ขึ้นอยู่กับการกำหนดค่า bean / แอปพลิเคชันให้อยู่ในรูปแบบ XML หรือไม่นั่นคือสมมติฐานที่ปลอดภัยหรือฉันล็อกผู้ใช้ไว้ในบางสิ่ง

และคำตอบนี้เปลี่ยนไปในสภาพแวดล้อมของเว็บหรือไม่ถ้าหากคลาสใดของฉันจำเป็นต้องตระหนักถึงสปริงพวกเขามีแนวโน้มที่จะต้องการApplicationContextหรือไม่

ขอบคุณสำหรับความช่วยเหลือ ฉันรู้ว่าคำถามเหล่านี้อาจตอบได้ในคู่มืออ้างอิง แต่ฉันมีปัญหาในการหารายละเอียดที่ชัดเจนของอินเทอร์เฟซทั้งสองนี้และข้อดี / ข้อเสียของแต่ละข้อโดยไม่ต้องอ่านผ่านคู่มือด้วยหวีฟัน

คำตอบ:


209

สปริงเอกสารนี้ยอดเยี่ยมในเรื่องนี้: 3.8.1 BeanFactory หรือ ApplicationContext . พวกเขามีตารางพร้อมการเปรียบเทียบฉันจะโพสต์ตัวอย่าง:

โรงงานถั่ว

  • การเริ่มต้นถั่ว / การเดินสายไฟ

บริบทของแอปพลิเคชัน

  • การเริ่มต้นถั่ว / การเดินสายไฟ
  • การลงทะเบียนตัวประมวลผล BeanPost อัตโนมัติ
  • การลงทะเบียน BeanFactoryPostProcessor อัตโนมัติ
  • การเข้าถึงแหล่งข้อมูล Message ที่แสนสะดวก (สำหรับ i18n)
  • สิ่งพิมพ์ ApplicationEvent

ดังนั้นหากคุณต้องการจุดใด ๆ ที่แสดงในด้านบริบทของแอปพลิเคชันคุณควรใช้ ApplicationContext


3
BeanFactory มีน้ำหนักเบา แต่ถ้าคุณกำลังจะใช้ Spring "เป็นของจริง" คุณอาจไปกับ ApplicationContext: มีค่าใช้จ่ายที่เกี่ยวข้องน้อยมากหากคุณไม่ได้ใช้คุณสมบัติแฟนซี แต่ก็ยังคงมีอยู่ สำหรับ if / เมื่อคุณใช้มัน
MetroidFan2002

2
หมายความว่าอย่างไรเมื่อคุณพูดว่า "Automatic BeanPostPorcessor regisgration"? หมายความว่าคลาสนั้นไม่จำเป็นต้องใช้อินเทอร์เฟซนั้นหรือไม่
Abidi

2
ApplicationContext รองรับ AOP กับ BeanFactory
ininprsr

1
ด้วยBeanFactoryเราสามารถส่งผ่านพารามิเตอร์คอนสตรัคแบบไดนามิก แต่ด้วยที่ApplicationContextเราทำไม่ได้
Half Blood Prince

1
หมายเหตุสำคัญจากเอกสาร Spring ที่เชื่อมโยง: "รุ่นของ Spring 2.0 ขึ้นไปใช้ประโยชน์อย่างมากจากจุดส่วนขยาย BeanPostProcessor (เพื่อให้เกิดผลกระทบต่อการพร็อกซี่และสิ่งที่คล้ายกัน) และถ้าคุณใช้เพียง BeanFactory ธรรมดา และ AOP จะไม่มีผล (อย่างน้อยก็ไม่มีขั้นตอนเพิ่มเติมในส่วนของคุณ) "
mark.monteiro

52

ฤดูใบไม้ผลิมีสองชนิดของ IOC ภาชนะหนึ่งและมีที่อื่น XMLBeanFactoryApplicationContext

+---------------------------------------+-----------------+--------------------------------+
|                                       | BeanFactory     |       ApplicationContext       |
+---------------------------------------+-----------------+--------------------------------+
| Annotation support                    | No              | Yes                            |
| BeanPostProcessor Registration        | Manual          | Automatic                      |
| implementation                        | XMLBeanFactory  | ClassPath/FileSystem/WebXmlApplicationContext|
| internationalization                  | No              | Yes                            |
| Enterprise services                   | No              | Yes                            |
| ApplicationEvent publication          | No              | Yes                            |
+---------------------------------------+-----------------+--------------------------------+

ป้อนคำอธิบายรูปภาพที่นี่

  • FileSystemXmlApplicationContext ถั่วโหลดผ่านเส้นทางเต็ม
  • ClassPathXmlApplicationContext ถั่วโหลดผ่าน CLASSPATH
  • XMLWebApplicationContextและAnnotationConfigWebApplicationContextbeans โหลดผ่านบริบทของเว็บแอปพลิเคชัน
  • AnnotationConfigApplicationContext กำลังโหลด Spring beans จากการกำหนดค่าตามหมายเหตุ

ตัวอย่าง:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
  • ApplicationContextเป็นภาชนะเริ่มต้นโดยContextLoaderListenerหรือContextLoaderServletกำหนดไว้ในweb.xmlและContextLoaderPluginกำหนดstruts-config.xmlมา

หมายเหตุ : XmlBeanFactoryจะเลิกเป็นของฤดูใบไม้ผลิ 3.1 ในความโปรดปรานของDefaultListableBeanFactoryXmlBeanDefinitionReaderและ


2
AnnotationConfigApplicationContext ไม่ใช่ -AnnotationConfigWebApplicationContext- ด้านล่าง ClassPathXmlApplicationContext ในแผนภาพ
Akhil Jain

48

สำหรับผมแล้วความแตกต่างหลักให้เลือกBeanFactoryมากกว่าApplicationContextน่าจะเป็นที่ApplicationContextจะ pre-instantiate ทั้งหมดของถั่ว จากฤดูใบไม้ผลิเอกสาร :

Spring ตั้งค่าคุณสมบัติและแก้ไขการพึ่งพาได้ช้าที่สุดเมื่อสร้างถั่วขึ้นจริง ซึ่งหมายความว่าสปริงคอนเทนเนอร์ที่โหลดอย่างถูกต้องในภายหลังสามารถสร้างข้อยกเว้นเมื่อคุณร้องขอวัตถุถ้ามีปัญหาในการสร้างวัตถุนั้นหรือการอ้างอิงอย่างใดอย่างหนึ่ง ตัวอย่างเช่น bean ส่งข้อยกเว้นอันเป็นผลมาจากคุณสมบัติที่ขาดหายไปหรือไม่ถูกต้อง การมองเห็นที่อาจล่าช้านี้ของปัญหาการกำหนดค่าบางอย่างคือสาเหตุที่การใช้งาน ApplicationContext โดยค่าเริ่มต้นอินสแตนซ์ของถั่วซิงเกิลล่วงหน้า ด้วยค่าใช้จ่ายของเวลาและหน่วยความจำล่วงหน้าเพื่อสร้าง bean เหล่านี้ก่อนที่จะต้องใช้จริงคุณจะพบปัญหาการกำหนดค่าเมื่อ ApplicationContext ถูกสร้างขึ้นในภายหลัง คุณยังคงสามารถแทนที่พฤติกรรมเริ่มต้นนี้เพื่อให้ถั่วแบบซิงเกิลจะขี้เกียจเริ่มต้นแทนที่จะถูกสร้างอินสแตนซ์ล่วงหน้า

ด้วยเหตุนี้ฉันจึงเลือกBeanFactoryใช้ในการทดสอบบูรณาการ / ประสิทธิภาพเนื่องจากฉันไม่ต้องการโหลดแอปพลิเคชันทั้งหมดสำหรับการทดสอบถั่วที่แยกได้ อย่างไรก็ตาม - และบางคนแก้ไขให้ฉันถ้าฉันผิด - BeanFactoryไม่รองรับการclasspathกำหนดค่า XML ดังนั้นBeanFactoryและApplicationContextแต่ละให้คุณลักษณะที่สำคัญผมอยาก แต่ไม่ได้ทั้ง

ใกล้ที่ฉันสามารถบอกได้ว่าในเอกสารประกอบเกี่ยวกับการแทนที่พฤติกรรมการเริ่มต้นอินสแตนซ์ที่เกิดขึ้นในการกำหนดค่าและเป็นแบบต่อถั่วดังนั้นฉันไม่สามารถตั้งค่าแอตทริบิวต์ "lazy-init" ในไฟล์ XML ได้หรือไม่ ยังคงติดตั้งรุ่นสำหรับการทดสอบและอีกรุ่นหนึ่งสำหรับการปรับใช้

สิ่งที่ฉันทำคือการขยาย ClassPathXmlApplicationContextถั่วเพื่อโหลดอย่างเกียจคร้านเพื่อใช้ในการทดสอบเช่น:

public class LazyLoadingXmlApplicationContext extends ClassPathXmlApplicationContext {

    public LazyLoadingXmlApplicationContext(String[] configLocations) {
        super(configLocations);
    }

    /**
     * Upon loading bean definitions, force beans to be lazy-initialized.
     * @see org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
     */

    @Override
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
        super.loadBeanDefinitions(reader);
        for (String name: reader.getBeanFactory().getBeanDefinitionNames()) {
            AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) reader.getBeanFactory().getBeanDefinition(name);
            beanDefinition.setLazyInit(true);
        }
    }

}

2
ฉันจะยืนยันว่าหากการทดสอบหน่วยของคุณกำลังโหลดบริบทแบบเต็มของฤดูใบไม้ผลิพวกเขาไม่ใช่ "การทดสอบหน่วย" แต่เป็นการทดสอบการรวม
matt b

1
จุดดี. ในกรณีของฉันฉันต้องการโหลดถั่วจากบริบทสำหรับการทดสอบประสิทธิภาพและการรวมและเขียน "การทดสอบหน่วย" เป็นนิสัย ฉันแก้ไขคำตอบของฉันแล้ว
Lyle

2
BeanFactory doesn't support classpath XML configuration.ฉันคิดว่ามันทำ: stackoverflow.com/questions/5231371/ …
Xtreme Biker

29

หากต้องการเพิ่มคำตอบของ Miguel Ping นี่คืออีกส่วนหนึ่งจากเอกสารที่ตอบคำถามเช่นนี้:

เวอร์ชั่นย่อ: ใช้ ApplicationContext เว้นเสียแต่ว่าคุณจะมีเหตุผลที่ดีในการไม่ทำเช่นนั้น สำหรับบรรดาของคุณที่กำลังมองหาความลึกมากกว่าเล็กน้อยสำหรับ 'แต่ทำไม' ของคำแนะนำข้างต้นให้อ่าน

(โพสต์สิ่งนี้สำหรับสามเณร Spring อนาคตใด ๆ ที่อาจอ่านคำถามนี้)


19
  1. ApplicationContext เป็นวิธีที่ต้องการมากกว่า BeanFactory

  2. ฤดูใบไม้ผลิในรุ่นใหม่จะถูกแทนที่ด้วยBeanFactory ApplicationContextแต่ยังคงBeanFactoryมีอยู่สำหรับความเข้ากันได้แบบย้อนหลัง

  3. ApplicationContext extends BeanFactory และมีประโยชน์ดังต่อไปนี้
    • สนับสนุนสากลสำหรับข้อความ
    • สนับสนุนการเผยแพร่เหตุการณ์ไปยังผู้ฟังที่ลงทะเบียน
    • การเข้าถึงทรัพยากรเช่น URL และไฟล์

13

ApplicationContext: โหลดสปริงถั่วที่กำหนดค่าในไฟล์กำหนดค่าสปริงและจัดการวงจรชีวิตของสปริงถั่วเป็นและเมื่อเริ่มต้นคอนเทนเนอร์จะไม่รอจนกว่าgetBean ("springbeanref")จะถูกเรียกใช้

BeanFactory โหลดสปริงถั่วที่กำหนดค่าในไฟล์กำหนดค่าสปริงจัดการวงจรชีวิตของสปริงถั่วเมื่อเราเรียกgetBean ("springbeanref")ดังนั้นเมื่อเราเรียกใช้getBean ("springbeanref")ในช่วงเวลาที่วงจรชีวิตสปริงเริ่ม .


12

ฉันคิดว่าการใช้ ApplicationContext จะดีกว่าเสมอเว้นแต่คุณจะอยู่ในสภาพแวดล้อมแบบพกพาเหมือนกับที่มีคนอื่นพูดไว้แล้ว ApplicationContext มีฟังก์ชันการทำงานมากขึ้นและแน่นอนคุณต้องการใช้ PostProcessors เช่น RequiredAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor และ CommonAnnotationBeanPostProcessor ของคุณและคุณสามารถใช้คำอธิบายประกอบเช่น @Required, @PostConstructes ฯลฯ .

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

หากคุณเขียนแอปแบบสแตนด์อโลนให้โหลด ApplicationContext ในวิธีการหลักของคุณโดยใช้ ClassPathXmlApplicationContext และรับ bean หลักและเรียกใช้ run () (หรือวิธีการใดก็ได้) เพื่อเริ่มแอปของคุณ หากคุณกำลังเขียนเว็บแอปให้ใช้ ContextLoaderListener ใน web.xml เพื่อสร้าง ApplicationContext และคุณสามารถรับได้ในภายหลังจาก ServletContext ไม่ว่าคุณจะใช้ JSP, JSF, JSTL, struts, Tapestry ฯลฯ .

นอกจากนี้อย่าลืมว่าคุณสามารถใช้ไฟล์กำหนดค่าสปริงหลายไฟล์และคุณสามารถสร้าง ApplicationContext ได้โดยการแสดงรายการไฟล์ทั้งหมดในคอนสตรัคเตอร์ (หรือแสดงรายการในคอนเท็กซ์ Param สำหรับ ContextLoaderListener) หรือคุณสามารถโหลดไฟล์กำหนดค่าหลักที่มี งบการนำเข้า คุณสามารถอิมพอร์ตไฟล์คอนฟิกูเรชัน Spring ไปยังไฟล์คอนฟิกูเรชัน Spring อื่นโดยใช้ <import resource = "otherfile.xml" /> ซึ่งมีประโยชน์มากเมื่อคุณสร้าง ApplicationContext โดยทางโปรแกรมในวิธีการหลักและโหลดไฟล์กำหนดค่า Spring เพียงไฟล์เดียว


6

ส่วนใหญ่แล้ว ApplicationContext เป็นที่ต้องการยกเว้นว่าคุณต้องการประหยัดทรัพยากรเช่นในแอปพลิเคชันมือถือ

ฉันไม่แน่ใจว่าขึ้นอยู่กับรูปแบบ XML แต่ฉันค่อนข้างมั่นใจว่าการใช้งานที่พบบ่อยที่สุดของ ApplicationContext นั้นเป็น XML เช่น ClassPathXmlApplicationContext, XmlWebApplicationContext และ FileSystemXmlApplicationContext นี่เป็นเพียงสามอย่างที่ฉันเคยใช้

หากคุณกำลังพัฒนาแอปพลิเคชันบนเว็บคุณต้องบอกว่าคุณจะต้องใช้ XmlWebApplicationContext

หากคุณต้องการให้ถั่วของคุณรับทราบถึง Spring คุณสามารถให้พวกเขาใช้ BeanFactoryAware และ / หรือ ApplicationContextAware สำหรับสิ่งนั้นเพื่อให้คุณสามารถใช้ BeanFactory หรือ ApplicationContext และเลือกอินเตอร์เฟสที่จะใช้


นี่คือส่วนที่เกี่ยวข้องจากเอกสารเนื่องจากApplicationContextรวมถึงฟังก์ชั่นทั้งหมดของBeanFactoryมันจึงแนะนำให้ใช้ในการตั้งค่าBeanFactoryยกเว้นในบางสถานการณ์ที่ จำกัด เช่นในAppletที่ที่การใช้หน่วยความจำอาจมีความสำคัญและอาจเพิ่มกิโลไบต์เล็กน้อย สร้างความแตกต่าง. อย่างไรก็ตามสำหรับแอปพลิเคชันและระบบขององค์กรส่วนใหญ่ 'ทั่วไป' ApplicationContextสิ่งที่คุณต้องการใช้คือ
M. Atif Riaz

6

ความแตกต่างระหว่างBeanFactoryและApplicationContextมีดังต่อไปนี้:

  1. BeanFactory ใช้การเริ่มต้นที่ขี้เกียจแต่ ApplicationContext ใช้การเริ่มต้นที่กระตือรือร้น ในกรณีของ BeanFactory bean จะถูกสร้างขึ้นเมื่อคุณเรียกใช้เมธอด getBeans () แต่ bean จะถูกสร้างขึ้นล่วงหน้าในกรณีของ ApplicationContext เมื่อมีการสร้างวัตถุ ApplicationContext
  2. BeanFactory ให้วัตถุทรัพยากรอย่างชัดเจนโดยใช้ไวยากรณ์แต่ ApplicationContext สร้างและจัดการวัตถุทรัพยากรด้วยตัวเอง
  3. BeanFactory ไม่สนับสนุนการเชื่อมโยงระหว่างกันภายในองค์กรแต่ ApplicationContext รองรับการทำให้เป็นสากล
  4. ด้วย BeanFactory การเพิ่มการอ้างอิงคำอธิบายประกอบไม่ได้รับการสนับสนุนแต่การฉีดขึ้นอยู่กับการอ้างอิงคำอธิบายประกอบได้รับการสนับสนุนใน ApplicationContext

ใช้ BeanFactory:

BeanFactory beanfactory = new XMLBeanFactory(new FileSystemResource("spring.xml"));
 Triangle triangle =(Triangle)beanFactory.getBean("triangle");

ใช้ ApplicationContext:

ApplicationContext context = new ClassPathXMLApplicationContext("spring.xml")
Triangle triangle =(Triangle)context.getBean("triangle");

5

BeanFactoryและApplicationContextทั้งสองเป็นวิธีรับถั่วจากที่เก็บIOCฤดูใบไม้ผลิของคุณแต่ก็ยังมีความแตกต่างอยู่บ้าง

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

BeanFactoryและApplicationContextทั้งสองเป็นอินเตอร์เฟส Java และ ApplicationContext ขยาย BeanFactory ทั้งคู่เป็นการกำหนดค่าโดยใช้ไฟล์การกำหนดค่า XML ในระยะสั้น BeanFactory ให้คุณสมบัติพื้นฐานการกลับกันของการควบคุม ( IoC ) และการพึ่งพาการฉีด ( DI ) ในขณะที่ ApplicationContext ให้บริการขั้นสูงคุณสมบัติ

BeanFactory ถูกแสดงโดยอินเตอร์เฟส " org.springframework.beans.factory " โดยที่ BeanFactory ซึ่งมีการนำไปใช้หลายอย่าง

ClassPathResource resource = new ClassPathResource("appConfig.xml");
XmlBeanFactory factory = new XmlBeanFactory(resource);

ความแตกต่าง

  1. BeanFactory instantiate bean เมื่อคุณเรียกใช้เมธอด getBean ()ขณะที่ ApplicationContext อินสแตนซ์ Singleton bean เมื่อเริ่มต้นคอนเทนเนอร์ไม่ต้องรอให้ getBean () ถูกเรียก

  2. BeanFactoryไม่ได้ให้การสนับสนุนสำหรับความเป็นสากล แต่ApplicationContextให้การสนับสนุน

  3. ความแตกต่างระหว่างBeanFactory vs ApplicationContextก็คือความสามารถในการเผยแพร่เหตุการณ์ไปยัง bean ที่ลงทะเบียนเป็นผู้ฟัง

  4. หนึ่งในการดำเนินงานที่เป็นที่นิยมของBeanFactoryอินเตอร์เฟซที่XMLBeanFactoryขณะที่หนึ่งของการดำเนินงานที่เป็นที่นิยมของApplicationContextอินเตอร์เฟซที่ClassPathXmlApplicationContext

  5. หากคุณกำลังใช้สายไฟรถยนต์และการใช้BeanFactoryกว่าที่คุณจำเป็นต้องลงทะเบียนAutoWiredBeanPostProcessorใช้ API ซึ่งคุณสามารถกำหนดค่าในรูปแบบ XML ถ้าคุณกำลังใช้ ApplicationContext โดยสรุปBeanFactoryนั้นใช้ได้สำหรับการทดสอบและการใช้งานที่ไม่ใช่การผลิต แต่ApplicationContextนั้นมีการใช้งานที่หลากหลายมากขึ้นและควรได้รับการสนับสนุนเหนือBeanFactory

  6. โดยค่าเริ่มต้นBeanFactoryรองรับการโหลดLazyและApplicationContextตามค่าเริ่มต้นการสนับสนุนAggresive loading


คุณช่วยอธิบาย # 1 ของคุณให้ชัดเจนยิ่งขึ้นได้ไหมถ้าฉันกำหนดถั่วเดี่ยวในไฟล์สปริงของฉันแล้วสปริงคอนเทนเนอร์จะสร้างซิงเกิลตันเหมือนกันมันสำคัญอย่างไรว่า BeanFactory หรือ ApplicationContext
pjj


3

ความแตกต่างอย่างหนึ่งระหว่างโรงงานผลิตถั่วและบริบทของแอปพลิเคชันคือเมื่อก่อนเรียกว่าถั่วอินสแตนซ์เพียงอย่างเดียวเมื่อคุณเรียกใช้เมธอด getBean () ในขณะที่ ApplicationContext จะสร้าง Singleton bean เมื่อเริ่มต้นคอนเทนเนอร์

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

หรือ

ApplicationContext context = new ClassPathXmlApplicationContext{"spring_dao.xml","spring_service.xml};

คุณสามารถใช้ไฟล์ xml หนึ่งไฟล์หรือมากกว่านั้นขึ้นอยู่กับความต้องการของโครงการของคุณ เนื่องจากฉันใช้ไฟล์ xml สองไฟล์ที่นี่สำหรับรายละเอียดการกำหนดค่าสำหรับคลาสบริการอื่น ๆ สำหรับคลาส dao นี่ ClassPathXmlApplicationContext เป็นลูกของ ApplicationContext

ค. BeanFactory Container เป็นคอนเทนเนอร์พื้นฐานมันสามารถสร้างวัตถุและฉีดพึ่งพา แต่เราไม่สามารถแนบบริการอื่น ๆ เช่นความปลอดภัยธุรกรรมข้อความ ฯลฯ เพื่อให้บริการทั้งหมดที่เราต้องใช้ ApplicationContext Container

d BeanFactory ไม่ได้ให้การสนับสนุนสำหรับความเป็นสากลเช่น i18n แต่ ApplicationContext ให้การสนับสนุน

อี BeanFactory Container ไม่รองรับคุณสมบัติของ AutoScanning (รองรับการอ้างอิงการพึ่งพาการอ้างอิง) แต่ ApplicationContext Container รองรับ

ฉ Beanfactory Container จะไม่สร้างวัตถุ bean จนกว่าจะถึงเวลาร้องขอ นั่นหมายถึง Beanfactory Container จะโหลดถั่วอย่างเกียจคร้าน ในขณะที่ ApplicationContext Container สร้างวัตถุของ Singleton bean ในเวลาที่โหลดเท่านั้น มันหมายความว่ามีการโหลดในช่วงต้น

ก. Beanfactory Container รองรับเพียงสองขอบเขต (ซิงเกิลและต้นแบบ) ของถั่ว แต่ ApplicationContext Container รองรับขอบเขต beans ทั้งหมด


จุด a และ f เหมือนกัน สามารถนำมารวมกันได้
dhana1310

3

โดยทั่วไปเราสามารถสร้างวัตถุสปริงคอนเทนเนอร์ในสองวิธี

  1. ใช้ BeanFactory
  2. ใช้ ApplicationContext

ทั้งสองเป็นอินเตอร์เฟส

ใช้คลาสการใช้งานเราสามารถสร้างวัตถุสำหรับภาชนะฤดูใบไม้ผลิ

มาถึงความแตกต่าง

BeanFactory:

  1. ไม่รองรับการฉีดตามคำอธิบายประกอบ

  2. ไม่รองรับ I18N

  3. โดยค่าเริ่มต้นมันรองรับการโหลด Lazy

  4. ไม่อนุญาตให้กำหนดค่าให้กับไฟล์การกำหนดค่าหลายไฟล์

เช่น BeanFactory context = new XmlBeanFactory (ทรัพยากรใหม่ ("applicationContext.xml"));

ApplicationContext

  1. สนับสนุนคำอธิบายประกอบแบบพึ่งพาการฉีด - @Autowired, @PreDestroy

  2. สนับสนุน I18N

  3. โดยเริ่มต้นการสนับสนุน Aggresive โหลด

  4. อนุญาตให้กำหนดค่าไฟล์การกำหนดค่าหลายไฟล์

ตัวอย่าง:
ApplicationContext context = new ClasspathXmlApplicationContext ("applicationContext.xml");


1

อ้างอิงเอกสารนี้จาก Spring Docs:

http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#context-introduction-ctx-vs-beanfactory

5.15.1 BeanFactory หรือ ApplicationContext?

ใช้ ApplicationContext เว้นแต่คุณจะมีเหตุผลที่ดีในการไม่ทำเช่นนั้น

เนื่องจาก ApplicationContext มีฟังก์ชั่นทั้งหมดของ BeanFactory โดยทั่วไปจะแนะนำให้ใช้กับ BeanFactory ยกเว้นในบางสถานการณ์เช่นใน Applet ที่ปริมาณการใช้หน่วยความจำอาจมีความสำคัญและอาจเพิ่มความแตกต่างเล็กน้อย อย่างไรก็ตามสำหรับแอปพลิเคชันและระบบทั่วไปขององค์กรส่วนใหญ่ ApplicationContext คือสิ่งที่คุณต้องการใช้ Spring 2.0 และใหม่กว่าใช้ประโยชน์อย่างมากจากจุดส่วนขยาย BeanPostProcessor (เพื่อให้เกิดผลกระทบต่อการใช้งานเป็นต้น) หากคุณใช้เพียง BeanFactory ธรรมดาจำนวนการสนับสนุนที่เหมาะสมเช่นการทำธุรกรรมและ AOP จะไม่มีผลอย่างน้อยก็ไม่มีขั้นตอนพิเศษเพิ่มเติมในส่วนของคุณ สถานการณ์นี้อาจทำให้สับสนเพราะไม่มีอะไรผิดปกติกับการกำหนดค่า


1

ApplicationContext เป็นพี่ใหญ่ของ BeanFactory และนี่จะเป็นสิ่งที่ BeanFactory จัดหาให้พร้อมกับสิ่งอื่น ๆ อีกมากมาย

นอกเหนือจากความสามารถในวงจรชีวิตของ org.springframework.beans.factory.BeanFactory มาตรฐานแล้วการประยุกต์ใช้ ApplicationContext จะตรวจจับและเรียกใช้ ApplicationContextAware beans รวมถึง ResourceLoaderAware, ApplicationEventPublisherAware และ MessageSourceAware


1

ในสถานการณ์ตามเวลาจริงความแตกต่างระหว่างคอนเทนเนอร์ Spring IOC Core (BeanFactory) และคอนเทนเนอร์ J2EE ขั้นสูง (ApplicationContext) มีดังนี้

  1. BeanFactory จะสร้างวัตถุสำหรับ beans (เช่นสำหรับคลาส POJO) ที่กล่าวถึงในไฟล์ spring.xml (<bean></bean> ) เฉพาะเมื่อคุณเรียกใช้เมธอด. getBean () แต่ในขณะที่ ApplicationContext จะสร้างออบเจ็กต์สำหรับถั่วทั้งหมด ( <bean></bean>ถ้าขอบเขตไม่ได้ กล่าวถึงอย่างชัดเจนว่า "Prototype") ซึ่งกำหนดค่าไว้ใน spring.xml ขณะที่โหลดไฟล์ spring.xml เอง

  2. BeanFactory: (Lazy container เพราะมันสร้างวัตถุสำหรับ beans เฉพาะเมื่อคุณโทรจากผู้ใช้ / คลาสหลักอย่างชัดเจน)

    /*
     * Using core Container - Lazy container - Because it creates the bean objects On-Demand
     */
    //creating a resource
    Resource r = (Resource) new ClassPathResource("com.spring.resources/spring.xml");
    //creating BeanFactory 
    BeanFactory factory=new XmlBeanFactory(r);
    
    //Getting the bean for the POJO class "HelloWorld.java"
    HelloWorld worldObj1 = (HelloWorld) factory.getBean("test");

    ApplicationContext: (คอนเทนเนอร์กระตือรือร้นเนื่องจากการสร้างวัตถุของถั่วซิงเกิลทั้งหมดขณะที่โหลดไฟล์ spring.xml เอง)

    ApplicationContext context = new ClassPathXmlApplicationContext("com/ioc/constructorDI/resources/spring.xml");
  3. ในทางเทคนิคแล้วแนะนำให้ใช้ ApplicationContext เพราะในแอปพลิเคชันแบบเรียลไทม์อ็อบเจ็กต์ถั่วจะถูกสร้างขึ้นในขณะที่แอปพลิเคชันเริ่มต้นทำงานในเซิร์ฟเวอร์เอง สิ่งนี้จะลดเวลาตอบสนองสำหรับคำขอของผู้ใช้เนื่องจากวัตถุนั้นพร้อมที่จะตอบสนองแล้ว


Stack Overflow ไม่ใช่ฟอรัมดังนั้นฉันได้แก้ไขคำตอบของคุณเพื่อตอบคำถามโดยตรงและหลีกเลี่ยงการเชิญการสนทนา
Jeffrey Bosboom

0

ฉันคิดว่าเป็นมูลค่าการกล่าวขวัญว่าตั้งแต่ฤดูใบไม้ผลิ 3 ถ้าคุณต้องการสร้างโรงงานคุณยังสามารถใช้@configurationคำอธิบายประกอบรวมกับความเหมาะสม@scope

@Configuration
public class MyFactory {

    @Bean
    @Scope("prototype")
    public MyClass create() {
        return new MyClass();
    }
}

สปริงของคุณควรมองเห็นโรงงานของคุณโดยใช้@ComponentScanคำอธิบายประกอบหรือการกำหนดค่า xml

บทความเกี่ยวกับ Spring Spring scopes จากเว็บไซต์ baeldung


0

ใช้ BeanFactory สำหรับแอปพลิเคชันที่ไม่ใช่เว็บเพราะรองรับเฉพาะถั่ว Singleton และ Prototype

ในขณะที่คอนเทนเนอร์ ApplicationContext รองรับขอบเขตของถั่วทั้งหมดดังนั้นคุณควรใช้มันสำหรับเว็บแอปพลิเคชัน


0

สรุป:

ApplicationContextมีฟังก์ชันการทำงานทั้งหมดของ BeanFactory ขอแนะนำโดยทั่วไปให้ใช้อดีต

มีบางสถานการณ์ที่ จำกัด เช่นในแอปพลิเคชันมือถือซึ่งการใช้หน่วยความจำอาจมีความสำคัญ

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

สำหรับข้อมูลเพิ่มเติมโปรดดูโพสต์บล็อกของฉัน:

ความแตกต่างระหว่าง BeanFactory และ ApplicationContext ใน Spring - บล็อก java spring จากพื้นฐาน


0

ฉันต้องอธิบาย BeanFactory & ApplicationContext

BeanFactory: BeanFactory เป็นส่วนต่อประสานสำหรับการเข้าถึง SpringBean Container มีมุมมองไคลเอ็นต์พื้นฐานของคอนเทนเนอร์ถั่ว อินเทอร์เฟซนั้นถูกนำมาใช้โดยคลาสอ็อบเจ็กต์ที่เก็บจำนวนนิยามของถั่วและแต่ละชื่อที่ไม่ซ้ำกันโดยชื่อสตริง
ขึ้นอยู่กับคำจำกัดความของถั่วโรงงานจะส่งคืนอินสแตนซ์ที่อินสแตนซ์นั้นอาจเป็นอินสแตนซ์ของวัตถุที่มีอยู่ อินสแตนซ์ชนิดใดที่จะส่งคืนขึ้นอยู่กับการกำหนดค่าของโรงงานถั่ว
โดยปกติโรงงาน Bean จะโหลดคำจำกัดความถั่วทั้งหมดที่เก็บไว้ในแหล่งกำหนดค่าเช่น XML ... ฯลฯ

BeanFactory เป็นคอนเทนเนอร์ที่ง่ายที่สุดที่ให้การสนับสนุนขั้นพื้นฐานสำหรับการพึ่งพาการฉีด

บริบทของ แอปพลิเคชันแอปพลิเคชันบริบทเป็นอินเทอร์เฟซกลางด้วยในแอปพลิเคชันสปริงที่ให้ข้อมูลการกำหนดค่าให้กับแอปพลิเคชัน ใช้งาน Bean Factory Interface

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

ApplicationContext ให้:

วิธีการ Bean Factory สำหรับการเข้าถึงส่วนประกอบแอปพลิเคชัน สืบทอดมาจาก ListableBeanFactory ความสามารถในการโหลดทรัพยากรไฟล์ในแบบทั่วไป สืบทอดมาจากอินเตอร์เฟส ResourceLoader ความสามารถในการเผยแพร่กิจกรรมไปยังผู้ฟังที่ลงทะเบียน รับมาจากส่วนต่อประสาน ApplicationEventPublisher ความสามารถในการแก้ไขข้อความรองรับสากล สืบทอดมาจากอินเตอร์เฟส MessageSource มรดกจากบริบทหลัก คำจำกัดความในบริบทที่สืบทอดจะมีความสำคัญเสมอ ยกตัวอย่างเช่นนี้หมายความว่าสามารถใช้บริบทของพาเรนต์เดียวโดยเว็บแอปพลิเคชั่นทั้งหมดในขณะที่แต่ละเซิร์ฟเล็ตมีบริบทลูกของตัวเองซึ่งไม่ขึ้นอยู่กับของเซิร์ฟเล็ตอื่น ๆ นอกเหนือจากความสามารถวงจรชีวิต BeanFactory มาตรฐานแล้ว

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