BeanFactory vs ApplicationContext

Ik ben vrij nieuw in het Spring Framework, ik heb gespeeld rond met het en het zetten van een paar voorbeelden apps samen in het kader van de evaluatie van Spring MVC voor gebruik in een aanstaande bedrijf project. Tot nu toe Ik hou echt van wat ik zie in het voorjaar van MVC, lijkt zeer eenvoudig te gebruiken en raadt u aan om write klassen die zijn zeer unit test-vriendelijk.

Net als een oefening, ik ben het schrijven van een belangrijkste methode voor één van mijn monster / test projecten. Een ding dat ik ben onduidelijk is precies het verschil tussen BeanFactoryen ApplicationContext– welke geschikt is om te gebruiken in welke omstandigheden

Ik begrijp dat ApplicationContextbreidt BeanFactory, maar als ik ben gewoon het schrijven van een eenvoudige belangrijkste methode, moet ik de extra functionaliteit die ApplicationContextbiedt? En precies wat voor soort extra functionaliteit doet ApplicationContextbieden?

Naast het beantwoorden van “wat moet ik gebruiken in een main () methode”, zijn er normen of richtlijnen voor zover die de uitvoering ik in een dergelijk scenario zou moeten gebruiken? Moet mijn main () methode worden geschreven afhangen van de boon / applicatieconfiguratie te zijn in XML-formaat – is dat een veilige aanname, of ben ik het vergrendelen van de gebruiker in iets specifieks

?

En doet dit antwoord verandering in een webomgeving – als een van mijn lessen die nodig zijn om zich bewust zijn van de Lente, zijn ze meer kans om behoefte ApplicationContext

Bedankt voor alle hulp. Ik weet dat veel van deze vragen worden waarschijnlijk beantwoord in de handleiding, maar ik heb een harde tijd vinden van een duidelijke verdeling van deze twee interfaces en de voors / tegens van elk zonder het lezen via de handleiding met een fijne kam.


Antwoord 1, Autoriteit 100%

De voorjaarsdocumenten zijn hier geweldig in: 3.8.1. BeanFactory of ApplicationContext?.
Ze hebben een tabel met een vergelijking, ik zal een fragment posten:

Bonenfabriek

  • Bean instantiatie/bedrading

Toepassingscontext

  • Bean instantiatie/bedrading
  • Automatische registratie van BeanPostProcessor
  • Automatische BeanFactoryPostProcessor-registratie
  • Handige toegang tot MessageSource (voor i18n)
  • ApplicationEvent-publicatie

Dus als u een van de punten op de Application Context-kant nodig heeft, moet u ApplicationContext gebruiken.


Antwoord 2, autoriteit 26%

Spring biedt twee soorten IOC-containers, de ene is XMLBeanFactoryen de andere is ApplicationContext.

BeanFactory ApplicationContext
Annotatie-ondersteuning Nee Ja
BeanPostProcessor-registratie Handleiding Automatisch
Implementatie XMLBeanFactory ClassPath/FileSystem/WebXmlApplicationContext
Internationalisering Nee Ja
Bedrijfsdiensten Nee Ja
ApplicationEvent-publicatie Nee Ja

Antwoord 3, autoriteit 22%

Voor mij lijkt het belangrijkste verschil om BeanFactoryte kiezen boven ApplicationContextte zijn dat ApplicationContextalle bonen vooraf zal instantiëren. Van de Lentedocs:

Spring stelt eigenschappen in en lost afhankelijkheden zo laat mogelijk op, wanneer de bean daadwerkelijk is gemaakt. Dit betekent dat een Spring-container die correct is geladen, later een uitzondering kan genereren wanneer u een object aanvraagt als er een probleem is bij het maken van dat object of een van zijn afhankelijkheden. De bean genereert bijvoorbeeld een uitzondering als gevolg van een ontbrekende of ongeldige eigenschap. Deze mogelijk vertraagde zichtbaarheid van sommige configuratieproblemen is de reden waarom ApplicationContext-implementaties standaard singleton-beans vooraf instantiëren. Ten koste van wat tijd en geheugen om deze bonen te maken voordat ze echt nodig zijn, ontdekt u configuratieproblemen wanneer de ApplicationContext wordt gemaakt, niet later. Je kunt dit standaardgedrag nog steeds negeren, zodat singleton-bonen lui initialiseren in plaats van vooraf te worden geïnstantieerd.

Daarom koos ik in eerste instantie voor BeanFactoryvoor gebruik in integratie-/prestatietests, omdat ik niet de hele applicatie wilde laden voor het testen van geïsoleerde bonen. Maar — en iemand corrigeert me als ik het mis heb — BeanFactoryondersteunt geen classpathXML-configuratie. Dus BeanFactoryen ApplicationContextbieden elk een cruciale functie die ik wilde, maar geen van beide.

Voor zover ik kan zien, vindt de opmerking in de documentatie over het negeren van standaardinstantiatiegedrag plaats in de configuratie, en het is per bean, dus ik kan niet zomaar het “lazy-init” -kenmerk in het XML-bestand of Ik zit vast met het onderhouden van een versie ervan voor test en één voor implementatie.

Wat ik uiteindelijk deed, was ClassPathXmlApplicationContextuitbreiden om lui bonen te laden voor gebruik in tests zoals:

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

Antwoord 4, autoriteit 15%

Om toe te voegen aan wat Miguel Ping antwoordde, hier is een andere sectie uit de documentatiedie dit ook beantwoordt:

Korte versie: gebruik een ApplicationContext tenzij je een hele goede reden hebt om dit niet te doen. Voor degenen onder u die op zoek zijn naar iets meer diepgang over het ‘maar waarom’ van de bovenstaande aanbeveling, blijf lezen.

(post dit voor toekomstige voorjaarsbeginners die deze vraag zouden kunnen lezen)


Antwoord 5, autoriteit 9%

  1. ApplicationContextheeft meer de voorkeur dan BeanFactory

  2. In nieuwe Spring-versies is BeanFactoryvervangen door ApplicationContext. Maar nog steeds bestaat BeanFactoryvoor achterwaartse compatibiliteit

  3. ApplicationContext extends BeanFactoryen heeft de volgende voordelen:
    • het ondersteunt internationalisering voor sms-berichten
    • het ondersteunt de publicatie van evenementen aan de geregistreerde luisteraars
    • toegang tot de bronnen zoals URL’s en bestanden

Antwoord 6, autoriteit 6%

ApplicationContext:
Het laadt lentebonen geconfigureerd in het lenteconfiguratiebestand en beheert de levenscyclus van de lenteboon als en WANNEER CONTAINER START. Het zal niet wachten tot getBean(“springbeanref”)wordt aangeroepen.

BeanFactory
Het laadt lentebonen geconfigureerd in het lenteconfiguratiebestand, beheert de levenscyclus van de lenteboon wanneer we de getBean(“springbeanref”)noemen. Dus wanneer we de getBean(“springbeanref”) aanroepen op het moment dat de levenscyclus van de lentebonen begint.


Antwoord 7, autoriteit 5%

Ik denk dat het beter is om altijd ApplicationContext te gebruiken, tenzij je in een mobiele omgeving zit, zoals iemand anders al zei. ApplicationContext heeft meer functionaliteit en u wilt zeker de PostProcessors gebruiken, zoals RequiredAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor en CommonAnnotationBeanPostProcessor, die u zullen helpen uw Spring-configuratiebestanden te vereenvoudigen, en u kunt annotaties zoals @Required, @PostConstruct, Beans @Resource, enz. .

Zelfs als je niet alle dingen gebruikt die ApplicationContext biedt, is het beter om het toch te gebruiken, en later als je besluit om wat bronnenmateriaal te gebruiken, zoals berichten of postprocessors, of het andere schema om transactieadviezen en zo heb je al een ApplicationContext en hoef je geen code te wijzigen.

Als u een zelfstandige app schrijft, laadt u de ApplicationContext in uw hoofdmethode, met behulp van een ClassPathXmlApplicationContext, en haalt u de hoofdbean op en roept u de run() (of welke methode dan ook) op om uw app te starten. Als u een web-app schrijft, gebruikt u de ContextLoaderListener in web.xml zodat deze de ApplicationContext maakt en u deze later uit de ServletContext kunt halen, ongeacht of u JSP, JSF, JSTL, struts, Tapestry, enz. gebruikt .

Onthoud ook dat u meerdere Spring-configuratiebestanden kunt gebruiken en dat u ofwel de ApplicationContext kunt maken door alle bestanden in de constructor op te sommen (of ze op te nemen in de contextparam voor de ContextLoaderListener), of u kunt gewoon een hoofdconfiguratie laden bestand met importstatements. U kunt een Spring-configuratiebestand in een ander Spring-configuratiebestand importeren met <import resource=”otherfile.xml” /> wat erg handig is wanneer u de ApplicationContext programmatisch in de hoofdmethode maakt en slechts één Spring-configuratiebestand laadt.


Antwoord 8, autoriteit 4%

Verschil tussen Beanfactory en ApplicationContext Volg:

  1. Beanfactory maakt gebruik van luie initialisatie maar applicationContext gebruikt enthousiaste initialisatie. In het geval van Beanfactory wordt Bean gecreëerd wanneer u de methode GetBeans () belt, maar Boon wordt vooraf gemaakt in geval van applicationContext wanneer het applicatieContext-object is aangemaakt.
  2. Beanfactory biedt expliciet een resource-object met behulp van syntaxis maar applicationContext creëert en beheert een resource-objecten op zichzelf.
  3. Beanfactory ondersteunt geen internatiolisatie maar applicationContext ondersteunt internationalisering.
  4. met banfactory annotatie gebaseerde afhankelijkheidsinjectie wordt niet ondersteund maar op annotatie gebaseerde afhankelijkheidsinjectie wordt ondersteund in applicationContext.

met beanfactory:

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

met behulp van applicationContext:

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

Antwoord 9, Autoriteit 3%

Voor het grootste deel heeft applicatieContext de voorkeur, tenzij u middelen wilt besparen, zoals op een mobiele applicatie.

Ik ben er niet zeker van, afhankelijk van het XML-formaat, maar ik ben er vrij zeker van dat de meest voorkomende implementaties van applicationContext de XML-exemplaren zijn, zoals classpathxmlapplicationContext, XMLWebapplicationContext, en filesystemxmlapplicationContext. Dat zijn de enige drie die ik ooit heb gebruikt.

Als u een web-app ontwikkelt, kunt u gerust zeggen dat u XmlWebApplicationContext moet gebruiken.

Als u wilt dat uw bonen op de hoogte zijn van Spring, kunt u ze hiervoor BeanFactoryAware en/of ApplicationContextAware laten implementeren, zodat u BeanFactory of ApplicationContext kunt gebruiken en kunt kiezen welke interface u wilt implementeren.


Antwoord 10, autoriteit 2%

BeanFactoryen ApplicationContextzijn beide manieren om bonen uit je lente IOC-container te halen, maar er zijn toch enkele verschillen.

BeanFactoryis de eigenlijke container die een aantal bean’s instantieert, configureert en beheert. Deze bonen werken meestal met elkaar samen en hebben dus onderlinge afhankelijkheden. Deze afhankelijkheden worden weerspiegeld in de configuratiegegevens die door de BeanFactory worden gebruikt.

BeanFactoryen ApplicationContextzijn beide Java-interfaces en ApplicationContext breidt BeanFactory uit. Beiden zijn configuratie met behulp van XML-configuratiebestanden. In het kort biedt BeanFactory basisfuncties voor Inversion of Control (IoC) en Dependency Injection (DI), terwijl ApplicationContext geavanceerdefuncties biedt.

Een BeanFactory wordt vertegenwoordigd door de interface “org.springframework.beans.factory” Waar BeanFactory, waarvoor meerdere implementaties zijn.

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

VERSCHIL

  1. BeanFactoryinstantiëren bean wanneer u de methode getBean()aanroept, terwijl ApplicationContext Singleton-bean instantiëren wanneer de container wordt gestart. Het wacht niet op getBean() om gebeld worden.

  2. BeanFactorybiedt geen ondersteuning voor internationalisering, maar ApplicationContextbiedt hiervoor ondersteuning.

  3. Een ander verschil tussen BeanFactoryen ApplicationContextis de mogelijkheid om gebeurtenissen te publiceren naar bonen die zijn geregistreerd als luisteraar.

  4. Een van de populaire implementaties van de BeanFactory-interface is XMLBeanFactory, terwijl een van de populaire implementaties van de ApplicationContext-interface is ClassPathXmlApplicationContext.

  5. Als u automatische bedrading gebruikt en BeanFactorygebruikt, moet u AutoWiredBeanPostProcessorregistreren met behulp van API die u in XML kunt configureren als u gebruikt Toepassingscontext. Samengevat is BeanFactorygeschikt voor testen en niet-productiegebruik, maar ApplicationContextis een meer functierijke containerimplementatie en zou de voorkeur moeten krijgen boven BeanFactory

  6. BeanFactoryondersteunt standaard Lazyladen en ApplicationContextstandaard ondersteuning Agressiefladen.


Antwoord 11, autoriteit 2%

Kenmerkenmatrix van Bean Factory versus applicatiecontext afkomstig van spring docs

schermafbeelding van functies van Beanfacotry en applicationContext


Antwoord 12, Autoriteit 2%

In principe kunnen we op twee manieren veercontainerobject maken

  1. met beanfactory.
  2. met behulp van applicationContext.

Beide zijn de interfaces,

Met behulp van implementatieklassen kunnen we object voor de veercontainer maken

Naar de verschillen

BeanFactory:

  1. ondersteunt de annotatie gebaseerde afhankelijkheidsinjectie niet.

  2. ondersteunt i18n niet.

  3. Standaard zijn ondersteuning luie laden.

  4. Het maakt het niet toe Configureren op meerdere configuratiebestanden.

EX: BeanFactory Context = NIEUWE XMLBEANFACTORY (NIEUWE BRONNEN (“ApplicationContext.xml”));

applicatieControlE

  1. Ondersteuning op annotatie gebaseerde afhankelijkheid injectie.-@autowired, @predestroy

  2. Ondersteuning i18n

  3. het is standaard ondersteuning Agressive Loading.

  4. het toestaan ​​om meerdere configuratiebestanden te configureren.

ex:
ApplicatieContext-context = Nieuwe ClassPathXmlapplicationContext (“applicationContext.xml”);


Antwoord 13, Autoriteit 2%

a. Eén verschil tussen bonenfabriek en toepassingscontext is dat voormalige alleen de bonen wanneer u de methode Getbean () belt, terwijl de applicatieContext Instantiates Singleton Bean wanneer de container is gestart, wacht niet op GetBean.

b.

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

of

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

U kunt een of meer xml-bestanden gebruiken, afhankelijk van uw projectvereisten. Omdat ik hier twee xml-bestanden gebruik, d.w.z. één voor configuratiedetails voor serviceklassen, andere voor dao-klassen. Hier is ClassPathXmlApplicationContext een kind van ApplicationContext.

c. BeanFactory Container is een basiscontainer, het kan alleen objecten maken en afhankelijkheden injecteren. Maar we kunnen geen andere services zoals beveiliging, transacties, berichten enz. koppelen om alle services te leveren die we nodig hebben om ApplicationContext Container te gebruiken.

d. BeanFactory biedt geen ondersteuning voor internationalisering, d.w.z. i18n, maar ApplicationContext biedt er wel ondersteuning voor.

e. BeanFactory Container ondersteunt niet de functie van AutoScanning (Ondersteuning Annotation-based dependency Injection), maar ApplicationContext Container ondersteunt.

v. Beanfactory Container zal pas op het moment van de aanvraag een bean-object maken. Het betekent dat Beanfactory Container lui bonen laadt. Terwijl ApplicationContext Container alleen op het moment van laden objecten van Singleton bean maakt. Het betekent dat er vroeg wordt geladen.

g. Beanfactory Container ondersteunt slechts twee scopes (singleton & prototype) van de bonen. Maar ApplicationContext Container ondersteunt het hele bereik van de bonen.


Antwoord 14

Verwijs naar dit document uit 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 of applicationContext?

Gebruik een applicationContext tenzij u een goede reden hebt om dit niet te doen.

Omdat de applicationContext alle functionaliteit van de beanfactory omvat, wordt het over het algemeen aanbevolen over de beanfactory, behalve een paar situaties zoals in een applet waar het geheugenverbruik van cruciaal belang kan zijn en een paar extra kilobytes een verschil kunnen maken. Voor de meeste typische ondernemingsaanvragen en -systemen is de applicationContext wat u wilt gebruiken. Spring 2.0 en later maakt zwaar gebruik van het BanpostProcessor-uitbreidingspunt (om een ​​proxying enzoveel te bewerkstelligen). Als u alleen een gewone beanfactory gebruikt, zal een behoorlijk aantal ondersteuning zoals transacties en AOP niet van kracht worden, althans niet zonder enkele extra stappen van uw kant. Deze situatie kan verwarrend zijn omdat er niets mis is met de configuratie.


Antwoord 15

ToepassingScontext is een grote broer van Beanfactory en dit zou alles wat beanfactory zijn, plus vele andere dingen.

Naast standaard Org.SpringFramework.Beans.Factory.BeanFactory Lifecycle-mogelijkheden, applicationContext-implementaties Detecteren en
Aanvragen van applicationContextAWare-bonen, evenals resourceuaderaware, applicatieeventenpublisislare en berichtenourceAeware-bonen.


Antwoord 16

In een realtime scenario is het verschil tussen de Spring IOC Core-container (BeanFactory) en de Advanced J2EE-container (ApplicationContext) als volgt.

  1. BeanFactory maakt alleen objecten voor de bonen (dwz voor POJO-klassen) die worden genoemd in het bestand spring.xml (<bean></bean>) wanneer u de .getBean() methode, maar terwijl ApplicationContext de objecten maakt voor alle bonen (<bean></bean>als het bereik niet expliciet wordt vermeld als “Prototype”) die in de lente zijn geconfigureerd. xml tijdens het laden van het bestand spring.xml zelf.

  2. BeanFactory: (Luie container omdat het de objecten voor de bonen alleen maakt wanneer je expliciet aanroept vanuit de gebruiker/hoofdklasse)

    /*
     * 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: (enthousiaste container vanwege het maken van de objecten van alle singleton-bonen terwijl het spring.xml-bestand zelf wordt geladen)

    ApplicationContext context = new ClassPathXmlApplicationContext("com/ioc/constructorDI/resources/spring.xml");
    
  3. Technisch gezien wordt het gebruik van ApplicationContext aanbevolen omdat in realtime toepassingen de bean-objecten worden gemaakt terwijl de toepassing op de server zelf wordt gestart. Dit verkort de reactietijd voor het gebruikersverzoek omdat de objecten al beschikbaar zijn om te reageren.


Antwoord 17

Ik denk dat het de moeite waard is om te vermelden dat als je sinds het voorjaar van 3 een fabriek wilt maken, je ook de @configurationannotatie gecombineerd met de juiste @scope

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

Uw fabriek zou zichtbaar moeten zijn per Spring-container met behulp van de @ComponentScanannotatie of xml-configuratie

Bon scopes-artikel van de baeldung-site


Antwoord 18

gebruik BeanFactory voor niet-webapplicaties omdat het alleen Singleton en Prototype bean-scopes ondersteunt.

Hoewel de ApplicationContext-container alle bean-scopes ondersteunt, moet u deze dus voor webtoepassingen gebruiken.


Antwoord 19

Samengevat:

De ApplicationContextbevat alle functionaliteit van de BeanFactory.
Het wordt over het algemeen aanbevolen om de eerste te gebruiken.

Er zijn enkele beperkte situaties, zoals in een mobiele applicatie, waar het geheugenverbruik van cruciaal belang kan zijn.

In die scenario’s kan het gerechtvaardigd zijn om de lichtere BeanFactoryte gebruiken. In de meeste zakelijke toepassingen is echter de ApplicationContextwat u wilt gebruiken.

Zie mijn blogbericht voor meer informatie:

Verschil tussen BeanFactory en ApplicationContext in het voorjaar – Het Java-lenteblog van de basis


Antwoord 20

Ik moet de BeanFactory & Toepassingscontext.

BeanFactory:BeanFactory is de root-interface voor toegang tot de SpringBean-container. Er is een basisclientweergave van een bean-container.
Die interface wordt geïmplementeerd door de objectklasse die het aantal bonendefinities bevat en die elk uniek worden geïdentificeerd door de String-naam
Afhankelijk van de Bean-definitie retourneert de fabriek de instantie die de instantie kan zijn van een ingesloten object of een enkele gedeelde instantie. Welk type instantie wordt geretourneerd, hangt af van de configuratie van de bonenfabriek.
Normaal gesproken laadt Bean Factory alle alle Beans-definities, die zijn opgeslagen in de configuratiebron zoals XML … enz.

BeanFactory is een eenvoudigste container die de basisondersteuning biedt voor Dependency Injection

Toepassingscontext
Applicatiecontext is een centrale interface met in de lente applicatie die de configuratie-informatie aan de applicatie levert. Het implementeert de Bean Factory Interface.

Toepassingscontext is een geavanceerde container, het voegt een geavanceerd niveau van bedrijfsspecifieke functionaliteit toe, zoals de mogelijkheid om het tekstbericht uit het eigenschappenbestand op te lossen….etc

Een ApplicationContext biedt:

Bean-factory-methoden voor toegang tot applicatiecomponenten. Overgenomen van ListableBeanFactory.
De mogelijkheid om bestandsbronnen op een generieke manier te laden. Overgenomen van de ResourceLoader-interface.
De mogelijkheid om gebeurtenissen te publiceren voor geregistreerde luisteraars. Overgenomen van de ApplicationEventPublisher-interface.
De mogelijkheid om berichten op te lossen, ter ondersteuning van internationalisering. Overgenomen van de MessageSource-interface.
Overerving uit een oudercontext. Definities in een afstammeling context hebben altijd prioriteit. Dit betekent bijvoorbeeld dat een enkele oudercontext kan worden gebruikt door een hele webtoepassing, terwijl elke servlet zijn eigen onderliggende context heeft die onafhankelijk is van die van een andere servlet.
Naast de standaard BeanFactory-levenscyclusmogelijkheden, detecteren en activeren ApplicationContext-implementaties ApplicationContextAware-beans en ResourceLoaderAware-, ApplicationEventPublisherAware- en MessageSourceAware-beans.


Antwoord 21

De BeanFactorybetekent veercontainer die luibean-objecten instantieert nadat de methode getBean()tijdens runtime is aangeroepen.

De ApplicationContextbetekent een spring-framework dat gretigbean-objecten instantieert tijdens de implementatietijd zonder of vóór het aanroepen van de getBean()-methode tijdens runtime.

p>

Other episodes