it-swarm.com.de

BeanFactory vs ApplicationContext

Ich bin ziemlich neu im Spring Framework, habe ein paar Beispiele für Apps zusammengestellt, um Spring MVC für ein bevorstehendes Unternehmensprojekt zu evaluieren. Bisher gefällt mir das, was ich in Spring MVC sehe, sehr gut und ich ermutige Sie, Klassen zu schreiben, die sehr Unit-Test-freundlich sind.

Nur als Übung schreibe ich eine Hauptmethode für eines meiner Beispiel-/Testprojekte. Eine Sache, über die ich unklar bin, sind die genauen Unterschiede zwischen BeanFactory und ApplicationContext - welche ist geeignet, um unter welchen Bedingungen verwendet zu werden?

Ich verstehe, dass ApplicationContextBeanFactory erweitert, aber wenn ich nur eine einfache Hauptmethode schreibe, benötige ich die zusätzliche Funktionalität, die ApplicationContext bietet? Und genau welche zusätzlichen Funktionen bietet ApplicationContext?

Gibt es neben der Antwort "Welche sollte ich in einer main () -Methode verwenden?" Noch Standards oder Richtlinien für die Implementierung in einem solchen Szenario? Sollte meine main () -Methode so geschrieben werden, dass sie von der Bean-/Anwendungskonfiguration im XML-Format abhängt - ist das eine sichere Annahme, oder sperre ich den Benutzer in etwas Bestimmtes ein?

Und ändert sich diese Antwort in einer Webumgebung - wenn eine meiner Klassen Spring berücksichtigen musste, ist es dann wahrscheinlicher, dass sie ApplicationContext benötigen?

Vielen Dank für jede Hilfe. Ich weiß, dass viele dieser Fragen wahrscheinlich im Referenzhandbuch beantwortet werden, aber es fällt mir schwer, eine klare Aufschlüsselung dieser beiden Schnittstellen und ihrer Vor- und Nachteile zu finden, ohne das Handbuch mit einem feinen Kamm durchzulesen.

218
matt b

Die Frühlingsdokumente sind in dieser Hinsicht großartig: .8.1. BeanFactory oder ApplicationContext? . Sie haben eine Tabelle mit einem Vergleich, ich werde ein Snippet posten:

Bohnenfabrik

  • Bean Instantiierung/Verkabelung

Anwendungskontext

  • Bean Instantiierung/Verkabelung
  • Automatische BeanPostProcessor-Registrierung
  • Automatische BeanFactoryPostProcessor-Registrierung
  • Bequemer MessageSource-Zugriff (für i18n)
  • ApplicationEvent-Veröffentlichung

Wenn Sie also einen der Punkte benötigen, die auf der Seite Anwendungskontext angezeigt werden, sollten Sie ApplicationContext verwenden.

200
Miguel Ping

Für mich scheint der Hauptunterschied bei der Auswahl von BeanFactory gegenüber ApplicationContext darin zu liegen, dass ApplicationContext alle Beans vorinstanziert. Von den Spring docs :

Spring legt Eigenschaften fest und löst Abhängigkeiten so spät wie möglich auf, wenn die Bean tatsächlich erstellt wird. Dies bedeutet, dass ein ordnungsgemäß geladener Spring-Container später eine Ausnahme generieren kann, wenn Sie ein Objekt anfordern, wenn beim Erstellen dieses Objekts oder einer seiner Abhängigkeiten ein Problem auftritt. Beispielsweise löst die Bean eine Ausnahme aufgrund einer fehlenden oder ungültigen Eigenschaft aus. Diese möglicherweise verzögerte Sichtbarkeit einiger Konfigurationsprobleme ist der Grund, warum ApplicationContext-Implementierungen Singleton-Beans standardmäßig vorinstanziieren. Auf Grund der Zeit und des Arbeitsspeichers, die erforderlich sind, um diese Beans zu erstellen, stellen Sie Konfigurationsprobleme fest, wenn der ApplicationContext erstellt wird, und nicht später. Sie können dieses Standardverhalten weiterhin außer Kraft setzen, sodass Singleton-Beans nicht vorab instanziiert, sondern nur verzögert initialisiert werden.

Vor diesem Hintergrund habe ich BeanFactory für die Verwendung in Integrations-/Leistungstests ausgewählt, da ich nicht die gesamte Anwendung zum Testen von isolierten Beans laden wollte. Allerdings - und jemand korrigiert mich, wenn ich falsch liege - unterstützt BeanFactory keine classpath XML-Konfiguration. Also bieten BeanFactory und ApplicationContext jeweils eine wichtige Funktion, die ich wollte, aber beides auch nicht.

Soweit ich das beurteilen kann, findet der Hinweis in der Dokumentation zum Überschreiben des Standard-Instanziierungsverhaltens in der Konfiguration statt und bezieht sich auf eine Bean. Ich kann also nicht einfach das Attribut "Lazy-Init" in der XML-Datei festlegen, oder ich bin steckengeblieben eine Version davon für Test und eine für die Bereitstellung.

Am Ende habe ich ClassPathXmlApplicationContext erweitert, um Beans für Tests wie diesen zu laden:

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);
        }
    }

}
46
Lyle

Spring bietet zwei Arten von IOC Container, einer ist XMLBeanFactory und der andere ist ApplicationContext.

+---------------------------------------+-----------------+--------------------------------+
|                                       | 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                            |
+---------------------------------------+-----------------+--------------------------------+

enter image description here

  • FileSystemXmlApplicationContext Beans werden über den gesamten Pfad geladen.
  • ClassPathXmlApplicationContext Beans, die durch den CLASSPATH geladen wurden
  • XMLWebApplicationContext und AnnotationConfigWebApplicationContext Beans, die über den Webanwendungskontext geladen werden.
  • AnnotationConfigApplicationContext Laden von Spring Beans aus einer Annotation-basierten Konfiguration.

beispiel:

  ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
  • ApplicationContext ist der Container, der durch einen ContextLoaderListener oder ContextLoaderServlet initialisiert wird, der in einem web.xml und ContextLoaderPlugin definiert in struts-config.xml.

Hinweis : XmlBeanFactory ist veraltet ab Frühjahr 3.1 zugunsten von DefaultListableBeanFactory und XmlBeanDefinitionReader.

41
Premraj

Um das, was Miguel Ping beantwortet hat, zu ergänzen, ist hier ein weiterer Abschnitt aus der Dokumentation , der auch dies beantwortet:

Kurzversion: Verwenden Sie einen ApplicationContext, es sei denn, Sie haben einen guten Grund, dies nicht zu tun. Für diejenigen von Ihnen, die nach etwas mehr Tiefe als dem "Aber warum" der obigen Empfehlung suchen, lesen Sie weiter.

(Posten Sie dies für alle zukünftigen Spring-Neulinge, die diese Frage lesen könnten.)

29
matt b
  1. ApplicationContext ist bevorzugter als BeanFactory

  2. In neuen Spring-Versionen wird BeanFactory durch ApplicationContext ersetzt. Aus Gründen der Rückwärtskompatibilität ist BeanFactory jedoch noch vorhanden

  3. ApplicationContext extends BeanFactory und hat folgende Vorteile
    • es unterstützt die Internationalisierung von Textnachrichten
    • es unterstützt die Veröffentlichung von Ereignissen für registrierte Zuhörer
    • zugriff auf Ressourcen wie URLs und Dateien
18
srinivas reddy

Ich denke, es ist besser, immer ApplicationContext zu verwenden, es sei denn, Sie befinden sich in einer mobilen Umgebung, wie bereits jemand anderes gesagt hat. ApplicationContext bietet mehr Funktionen, und Sie möchten auf jeden Fall die PostProcessors wie RequiredAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor und CommonAnnotationBeanPostProcessor verwenden, um Ihre Spring-Konfigurationsdateien zu vereinfachen. Außerdem können Sie Anmerkungen wie @Required, @PostConstruct usw. verwenden .

Auch wenn Sie nicht alle von ApplicationContext angebotenen Informationen verwenden, ist es besser, sie trotzdem zu verwenden, und später, wenn Sie sich dazu entschließen, Ressourcen wie Nachrichten oder Postprozessoren oder das andere Schema zum Hinzufügen von Transaktionshinweisen und dergleichen zu verwenden verfügt bereits über einen ApplicationContext und muss keinen Code ändern.

Wenn Sie eine eigenständige App schreiben, laden Sie den ApplicationContext mithilfe eines ClassPathXmlApplicationContext in Ihre Hauptmethode, rufen Sie die Haupt-Bean auf und rufen Sie run () (oder eine andere Methode) auf, um Ihre App zu starten. Wenn Sie eine Webanwendung schreiben, verwenden Sie den ContextLoaderListener in web.xml, damit er den ApplicationContext erstellt und Sie ihn später vom ServletContext abrufen können, unabhängig davon, ob Sie JSP, JSF, JSTL, Struts, Tapestry usw. Verwenden .

Denken Sie auch daran, dass Sie mehrere Spring-Konfigurationsdateien verwenden und entweder den ApplicationContext erstellen können, indem Sie alle Dateien im Konstruktor auflisten (oder sie im Kontextparameter für den ContextLoaderListener auflisten), oder Sie können einfach eine Hauptkonfigurationsdatei laden, die über Folgendes verfügt Anweisungen importieren. Sie können eine Spring-Konfigurationsdatei mithilfe von <import resource = "otherfile.xml" /> in eine andere Spring-Konfigurationsdatei importieren. Dies ist sehr nützlich, wenn Sie den ApplicationContext in der Hauptmethode programmgesteuert erstellen und nur eine Spring-Konfigurationsdatei laden.

12
Chochos

ApplicationContext: Lädt in der Spring-Konfigurationsdatei konfigurierte Spring-Beans und verwaltet den Lebenszyklus der Spring-Beans als und WENN CONTAINER STARTET. Es wird nicht warten bis getBean ("springbeanref") heißt.

BeanFactory Lädt in der Spring-Konfigurationsdatei konfigurierte Spring-Beans und verwaltet den Lebenszyklus der Spring-Beans, wenn wir getBean ("springbeanref") aufrufen. Wenn wir also - aufrufen getBean ("springbeanref") zum Zeitpunkt des Starts des Lebenszyklus der Bohne.

10
vinod

In den meisten Fällen wird ApplicationContext bevorzugt, es sei denn, Sie müssen Ressourcen wie bei einer mobilen Anwendung sparen.

Abhängig vom XML-Format bin ich mir nicht sicher, aber ich bin mir ziemlich sicher, dass die gängigsten Implementierungen von ApplicationContext XML-Implementierungen wie ClassPathXmlApplicationContext, XmlWebApplicationContext und FileSystemXmlApplicationContext sind. Das sind die einzigen drei, die ich jemals benutzt habe.

Wenn Sie eine Web-App entwickeln, müssen Sie mit Sicherheit XmlWebApplicationContext verwenden.

Wenn Sie möchten, dass Ihre Beans Spring kennen, können Sie dafür BeanFactoryAware und/oder ApplicationContextAware implementieren. Sie können also entweder BeanFactory oder ApplicationContext verwenden und die zu implementierende Schnittstelle auswählen.

6
Ryan Thames

Der Unterschied zwischen BeanFactory und ApplicationContext ist folgender:

  1. BeanFactory verwendet die verzögerte Initialisierung aber ApplicationContext verwendet die eifrige Initialisierung. Bei BeanFactory wird eine Bean erstellt, wenn Sie die Methode getBeans () aufrufen. Bei ApplicationContext wird die Bean jedoch im Voraus erstellt, wenn das ApplicationContext-Objekt erstellt wird.
  2. BeanFactory stellt explizit ein Ressourcenobjekt mit der Syntax aber ApplicationContext bereit, erstellt und verwaltet Ressourcenobjekte selbstständig.
  3. BeanFactory unterstützt keine Internationalisierung aber ApplicationContext unterstützt Internationalisierung.
  4. Mit BeanFactory wird die auf Annotationen basierende Abhängigkeitsinjektion nicht unterstützt aber Die auf Annotationen basierende Abhängigkeitsinjektion wird in ApplicationContext unterstützt.

Mit BeanFactory:

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

sing ApplicationContext:

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

5
Raman Gupta

BeanFactory und ApplicationContext beides sind Möglichkeiten, um Bohnen aus Ihrem Spring-Container zu holen IOC aber es gibt immer noch einige Unterschied.

BeanFactory ist der eigentliche Container, der eine Reihe von Beans instanziiert, konfiguriert und verwaltet. Diese Beans arbeiten normalerweise zusammen und sind daher voneinander abhängig. Diese Abhängigkeiten spiegeln sich in den von BeanFactory verwendeten Konfigurationsdaten wider.

BeanFactory und ApplicationContext sind beide Java Schnittstellen und ApplicationContext erweitert BeanFactory. Beide sind Konfigurationen mit Hilfe von XML-Konfigurationsdateien Inversion von Steuerungs--- (IoC) und Abhängigkeitsinjektions--- ([~ # ~] di [~ # ~]) -Funktionen, während ApplicationContext erweiterte -Funktionen bereitstellt.

Eine BeanFactory wird durch die Schnittstelle "org.springframework.beans.factory" dargestellt, für die es mehrere Implementierungen gibt.

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

UNTERSCHIED

  1. BeanFactory Bean instanziieren, wenn Sie getBean () aufrufen, während ApplicationContext die Singleton-Bean instanziiert, wenn der Container gestartet wird. Es wird nicht auf den Aufruf von getBean () gewartet.

  2. BeanFactory unterstützt die Internationalisierung nicht, aber ApplicationContext unterstützt sie.

  3. Ein weiterer Unterschied zwischen BeanFactory und ApplicationContext besteht in der Möglichkeit, Ereignisse für Beans zu veröffentlichen, die als Listener registriert sind.

  4. Eine der populären Implementierungen von BeanFactory ist XMLBeanFactory, während eine der populären Implementierungen von ApplicationContextClassPathXmlApplicationContext ist.

  5. Wenn Sie die automatische Verkabelung verwenden und BeanFactory verwenden, müssen Sie AutoWiredBeanPostProcessor mithilfe einer API registrieren, die Sie in XML konfigurieren können, wenn Sie ApplicationContext verwenden. Zusammenfassend ist BeanFactory für Testzwecke und Nichtproduktionszwecke in Ordnung, aber ApplicationContext ist eine funktionsreichere Containerimplementierung und sollte gegenüber BeanFactory bevorzugt werden

  6. BeanFactory standardmäßig seine Unterstützung Lazy Laden und ApplicationContext standardmäßig Unterstützung Aggresive Laden.

5

Funktionsmatrix von Bean Factory im Vergleich zum Anwendungskontext Quelle: Spring Docs

enter image description here

Screenshot der Funktionen von BeanFacotry und ApplicationContext

4
Lucky

ein. Ein Unterschied zwischen Bean-Factory und Anwendungskontext besteht darin, dass die Bean erst dann instanziiert wird, wenn Sie die Methode getBean () aufrufen, während ApplicationContext die Singleton-Bean instanziiert, wenn der Container gestartet wird. Es wird nicht auf den Aufruf von getBean gewartet.

b.

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

oder

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

Sie können je nach Projektanforderung eine oder mehrere XML-Dateien verwenden. Da ich hier zwei XML-Dateien verwende, d. H. Eine für Konfigurationsdetails für Serviceklassen, andere für Dao-Klassen. Hier ist ClassPathXmlApplicationContext dem ApplicationContext untergeordnet.

c. BeanFactory Container ist ein einfacher Container, der nur Objekte erstellen und Abhängigkeiten einfügen kann. Wir können jedoch keine anderen Dienste wie Sicherheit, Transaktionen, Nachrichten usw. hinzufügen, um alle Dienste bereitzustellen, die wir für die Verwendung von ApplicationContext Container benötigen.

d. BeanFactory bietet keine Unterstützung für die Internationalisierung, d. H. I18n, aber ApplicationContext bietet Unterstützung dafür.

e. BeanFactory Container unterstützt die AutoScanning-Funktion (Support Annotation based Dependency Injection) nicht, ApplicationContext Container jedoch.

f. Beanfactory Container erstellt erst zum Anforderungszeitpunkt ein Bean-Objekt. Dies bedeutet, dass Beanfactory Container Bohnen träge lädt. Während ApplicationContext Container Objekte von Singleton Bean nur zum Zeitpunkt des Ladens erstellt. Dies bedeutet, dass frühzeitig geladen wird.

g. Beanfactory Container unterstützen nur zwei Bereiche (Singleton & Prototyp) der Beans. ApplicationContext Container unterstützt jedoch den gesamten Beans-Bereich.

3
rajvineet

Grundsätzlich können wir Spring Container Objekte auf zwei Arten erstellen

  1. mit BeatFactory
  2. mit ApplicationContext

beides sind die Schnittstellen

mit Hilfe von Implementierungsklassen können wir Objekte für Springcontainer erstellen

kommen wir zu den Unterschieden

BeanFactory

  1. Unterstützt nicht die auf Annotation basierende Abhängigkeitsinjektion.

  2. Unterstützt kein I18N

  3. Standardmäßig unterstützt es Lazy Loading

  4. es ist nicht möglich, mehrere Konfigurationsdateien zu konfigurieren.

beispiel: BeanFactory context = new XmlBeanFactory (neue Ressource ("applicationContext.xml"));

Anwendungskontext

  1. Support Annotation-basierte Abhängigkeit [email protected], @PreDestroy

  2. Unterstützung I18N

  3. standardmäßig wird das aggressive Laden unterstützt.

  4. es ermöglicht die Konfiguration mehrerer Konfigurationsdateien.

ex:
ApplicationContext context = new ClasspathXmlApplicationContext ("applicationContext.xml");

In einem Echtzeitszenario ist der Unterschied zwischen dem Spring IOC Core-Container (BeanFactory) und dem Advanced J2EE-Container (ApplicationContext) wie folgt.

  1. BeanFactory erstellt Objekte für die Beans (d. H. Für POJO-Klassen), die in der Datei spring.xml (<bean></bean>) nur, wenn Sie die .getBean () -Methode aufrufen, während ApplicationContext die Objekte für alle Beans erstellt (<bean></bean>, wenn der Gültigkeitsbereich nicht explizit als "Prototype" angegeben ist), der in der Datei spring.xml konfiguriert wurde, während die Datei spring.xml selbst geladen wurde.

  2. BeanFactory: (Lazy Container, da die Objekte für die Beans nur erstellt werden, wenn Sie explizit von der Benutzer-/Hauptklasse aufrufen.)

    /*
     * 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: (Eifriger Container, da beim Laden der Datei spring.xml die Objekte aller Singleton-Beans erstellt werden.)

    ApplicationContext context = new ClassPathXmlApplicationContext("com/ioc/constructorDI/resources/spring.xml");
    
  3. Technisch wird die Verwendung von ApplicationContext empfohlen, da in Echtzeitanwendungen die Bean-Objekte erstellt werden, während die Anwendung auf dem Server selbst gestartet wird. Dies verringert die Antwortzeit für die Benutzeranforderung, da die Objekte bereits für die Antwort verfügbar sind.

1
Karthik Pon

ApplicationContext ist ein großer Bruder von BeanFactory und all dies und noch viele andere Dinge, die BeanFactory zu bieten hat.

Zusätzlich zu den standardmäßigen org.springframework.beans.factory.BeanFactory-Lebenszyklusfunktionen erkennen und rufen ApplicationContext-Implementierungen ApplicationContextAware-Beans sowie ResourceLoaderAware-, ApplicationEventPublisherAware- und MessageSourceAware-Beans auf.

Verweisen Sie auf dieses Dokument von 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 oder ApplicationContext?

Verwenden Sie einen ApplicationContext, es sei denn, Sie haben einen guten Grund, dies nicht zu tun.

Da der ApplicationContext alle Funktionen der BeanFactory enthält, wird er im Allgemeinen gegenüber der BeanFactory empfohlen, mit Ausnahme einiger Situationen, wie in einem Applet, in denen der Speicherverbrauch kritisch sein kann und einige zusätzliche Kilobyte den Unterschied ausmachen. Für die meisten typischen Unternehmensanwendungen und -systeme ist ApplicationContext jedoch genau das, was Sie verwenden möchten. In Spring 2.0 und höher wird der BeanPostProcessor-Erweiterungspunkt stark genutzt (um das Proxying usw. zu bewirken). Wenn Sie nur eine einfache BeanFactory verwenden, wird eine angemessene Menge an Unterstützung wie Transaktionen und AOP nicht wirksam, zumindest nicht ohne einige zusätzliche Schritte von Ihrer Seite. Diese Situation kann verwirrend sein, da an der Konfiguration nichts falsch ist.

1

In Summe:

Der ApplicationContext enthält alle Funktionen der BeanFactory. Es wird allgemein empfohlen, die erstere zu verwenden.

Es gibt einige eingeschränkte Situationen, z. B. in einer Mobilanwendung, in denen der Speicherverbrauch kritisch sein kann.

In diesen Fällen kann es gerechtfertigt sein, die leichtere BeanFactory zu verwenden. In den meisten Unternehmensanwendungen möchten Sie jedoch den ApplicationContext verwenden.

Weitere Informationen finden Sie in meinem Blog-Beitrag:

nterschied zwischen BeanFactory und ApplicationContext im Frühjahr - Das Java Spring-Blog aus den Grundlagen

0
Zoltán Raffai

verwenden Sie BeanFactory nicht für Webanwendungen, da es nur Singleton- und Prototype-Bean-Scopes unterstützt.

Während der ApplicationContext-Container alle Bean-Bereiche unterstützt, sollten Sie ihn für Webanwendungen verwenden.

0
Arun Raaj

Ich denke, es ist erwähnenswert, dass Sie seit Frühjahr 3, wenn Sie eine Fabrik erstellen möchten, auch die @configuration Anmerkung kombiniert mit dem richtigen @scope

@Configuration
public class MyFactory {

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

Ihre Fabrik sollte durch Spring Container mit der @ComponentScan Anmerkung oder XML-Konfiguration

Spring Bean Scopes Artikel von Baeldung Site

0