Pregunta

Soy bastante nuevo en Spring Framework, he estado jugando con él y reuniendo algunas aplicaciones de muestra con el fin de evaluar Spring MVC para su uso en un próximo proyecto de la empresa.Hasta ahora, realmente me gusta lo que veo en Spring MVC, parece muy fácil de usar y te alienta a escribir clases que sean muy amigables con las pruebas unitarias.

Solo como ejercicio, estoy escribiendo un método principal para uno de mis proyectos de muestra/prueba.Una cosa que no tengo clara son las diferencias exactas entre BeanFactory y ApplicationContext - ¿Cuál es apropiado para usar en qué condiciones?

Entiendo que ApplicationContext se extiende BeanFactory, pero si sólo estoy escribiendo un método principal simple, ¿necesito la funcionalidad adicional que ApplicationContext proporciona?¿Y exactamente qué tipo de funcionalidad adicional ofrece? ApplicationContext ¿proporcionar?

Además de responder "cuál debo usar en un método main()", ¿existen estándares o pautas sobre qué implementación debo usar en tal escenario?¿Debería escribirse mi método main() para que dependa de que la configuración del bean/aplicación esté en formato XML? ¿Es una suposición segura o estoy encerrando al usuario en algo específico?

¿Y esta respuesta cambia en un entorno web? Si alguna de mis clases necesitaba conocer Spring, ¿es más probable que lo necesite? ApplicationContext?

Gracias por cualquier ayuda.Sé que muchas de estas preguntas probablemente se respondan en el manual de referencia, pero me resulta difícil encontrar un desglose claro de estas dos interfaces y los pros y los contras de cada una sin leer el manual con detenimiento.

¿Fue útil?

Solución

Los documentos de primavera son excelentes en esto: 3.8.1. BeanFactory o ApplicationContext? . Tienen una tabla con una comparación, publicaré un fragmento:

Fábrica de frijoles

  • Instancia / cableado de frijol

Contexto de la aplicación

  • Instancia / cableado de frijol
  • Registro automático de BeanPostProcessor
  • Registro automático de BeanFactoryPostProcessor
  • Acceso conveniente a MessageSource (para i18n)
  • Publicación de ApplicationEvent

Entonces, si necesita alguno de los puntos presentados en el lado del Contexto de la Aplicación, debe usar el Contexto de la Aplicación.

Otros consejos

Para mí, la principal diferencia a la hora de elegir BeanFactory encima ApplicationContext parece ser eso ApplicationContext creará una instancia previa de todos los beans.De el Primavera documentos:

Spring establece propiedades y resuelve dependencias lo más tarde posible, cuando el bean realmente se crea.Esto significa que un contenedor Spring que se ha cargado correctamente puede generar más tarde una excepción cuando solicita un objeto si hay un problema al crear ese objeto o una de sus dependencias.Por ejemplo, el bean genera una excepción como resultado de una propiedad faltante o no válida.Esta visibilidad potencialmente retrasada de algunos problemas de configuración es la razón por la que las implementaciones de ApplicationContext crean instancias previas de beans singleton de forma predeterminada.A costa de algo de tiempo y memoria por adelantado para crear estos beans antes de que realmente se necesiten, descubrirá problemas de configuración cuando se crea ApplicationContext, no más tarde.Aún puede anular este comportamiento predeterminado para que los beans singleton se inicialicen de forma diferida, en lugar de crear instancias previas.

Teniendo esto en cuenta, inicialmente elegí BeanFactory para usar en pruebas de integración/rendimiento ya que no quería cargar la aplicación completa para probar beans aislados.Sin embargo, y que alguien me corrija si me equivoco, BeanFactory no es compatible classpath Configuración XML.Entonces BeanFactory y ApplicationContext cada uno proporciona una característica crucial que quería, pero ninguno de los dos.

Por lo que puedo decir, la nota en la documentación sobre la anulación del comportamiento de creación de instancias predeterminado tiene lugar en la configuración y es por bean, por lo que no puedo simplemente configurar el atributo "lazy-init" en el archivo XML o estoy Atascado manteniendo una versión para prueba y otra para implementación.

Lo que terminé haciendo fue extender ClassPathXmlApplicationContext para cargar beans de forma diferida para usarlos en pruebas como esta:

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

}

Spring proporciona dos tipos de contenedores IOC, uno es XMLBeanFactory y otro es 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 Frijoles cargados por el camino completo.
  • ClassPathXmlApplicationContext Beans cargados a través de CLASSPATH
  • XMLWebApplicationContext y AnnotationConfigWebApplicationContext beans cargados a través del contexto de la aplicación web.
  • AnnotationConfigApplicationContext Cargando Spring beans desde una configuración basada en anotaciones.

ejemplo:

  ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
  • ApplicationContext ¿El contenedor es inicializado por un ContextLoaderListener o ContextLoaderServlet definido en un web.xml y ContextLoaderPlugin definido en struts-config.xml.

Nota: XmlBeanFactory es obsoleto a partir de la primavera 3.1 a favor de DefaultListableBeanFactory y XmlBeanDefinitionReader.

Para agregar a lo que respondió Miguel Ping, aquí está otra sección de la documentación que también responde esto:

  

Versión corta: use un ApplicationContext a menos que tenga una buena razón para no hacerlo. Para aquellos de ustedes que buscan un poco más de profundidad en cuanto al "pero por qué" de la recomendación anterior, sigan leyendo.

(publicar esto para futuros novicios de Spring que puedan leer esta pregunta)

  1. ApplicationContext es una forma más preferida que BeanFactory

  2. En nuevas versiones de primavera BeanFactory se reemplaza con ApplicationContext.Pero aún BeanFactory existe para compatibilidad con versiones anteriores

  3. ApplicationContext extends BeanFactory y tiene los siguientes beneficios
    • admite la internacionalización de mensajes de texto
    • Admite la publicación de eventos para los oyentes registrados.
    • acceso a recursos como URL y archivos

Creo que es mejor usar siempre ApplicationContext, a menos que esté en un entorno móvil como ya dijo alguien más. ApplicationContext tiene más funcionalidad y definitivamente desea usar los PostProcessors como RequiredAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor y CommonAnnotationBeanPostProcessor, que lo ayudarán a simplificar sus archivos de configuración de Spring, y puede usar anotaciones como @Required, @PostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct, @RostConstruct .

Incluso si no usa todo lo que ofrece ApplicationContext, es mejor usarlo de todos modos, y luego si decide usar algunos recursos como mensajes o procesadores posteriores, o el otro esquema para agregar consejos transaccionales y de este modo, ya tendrá un ApplicationContext y no necesitará cambiar ningún código.

Si está escribiendo una aplicación independiente, cargue el ApplicationContext en su método principal, usando un ClassPathXmlApplicationContext, y obtenga el bean principal e invoque su ejecución () (o cualquier método) para iniciar su aplicación. Si está escribiendo una aplicación web, use ContextLoaderListener en web.xml para que cree el ApplicationContext y luego pueda obtenerlo del ServletContext, independientemente de si está utilizando JSP, JSF, JSTL, struts, Tapestry, etc. .

Además, recuerde que puede usar varios archivos de configuración de Spring y puede crear el ApplicationContext enumerando todos los archivos en el constructor (o enumerándolos en el parámetro de contexto para ContextLoaderListener), o simplemente puede cargar una configuración principal archivo que tiene declaraciones de importación. Puede importar un archivo de configuración de Spring en otro archivo de configuración de Spring utilizando & Lt; import resource = & Quot; otherfile.xml & Quot; / > lo cual es muy útil cuando crea programáticamente el ApplicationContext en el método principal y carga solo un archivo de configuración de Spring.

ApplicationContext: Carga spring beans configurados en el archivo de configuración de spring y gestiona el ciclo de vida del spring bean como y CUANDO COMIENZA EL CONTENEDOR. No esperará hasta que getBean (& Quot; springbeanref & Quot;) se llama.

BeanFactory  Carga spring beans configurados en el archivo de configuración de spring, gestiona el ciclo de vida del spring bean cuando llamamos a getBean (& Quot; springbeanref & Quot;) .Así que cuando llamamos a < strong> getBean (" springbeanref ") en el momento en que comienza el ciclo de vida del spring bean.

En su mayor parte, se prefiere ApplicationContext a menos que necesite guardar recursos, como en una aplicación móvil.

No estoy seguro de depender del formato XML, pero estoy bastante seguro de que las implementaciones más comunes de ApplicationContext son XML como ClassPathXmlApplicationContext, XmlWebApplicationContext y FileSystemXmlApplicationContext. Esos son los únicos tres que he usado.

Si está desarrollando una aplicación web, es seguro decir que necesitará usar XmlWebApplicationContext.

Si desea que sus beans estén al tanto de Spring, puede hacer que implementen BeanFactoryAware y / o ApplicationContextAware para eso, de modo que puede usar BeanFactory o ApplicationContext y elegir qué interfaz implementar.

BeanFactory y ApplicationContext son formas de obtener frijoles de su contenedor Spring IOC pero aún hay alguna diferencia.

BeanFactory es el contenedor real que crea instancias, configura y gestiona varios beans. Estos beans normalmente colaboran entre sí y, por lo tanto, tienen dependencias entre ellos. Estas dependencias se reflejan en los datos de configuración utilizados por BeanFactory.

BeanFactory y ApplicationContext son interfaces Java y ApplicationContext extiende BeanFactory. Ambos son de configuración utilizando archivos de configuración XML. En resumen, BeanFactory proporciona funciones básicas de Inversión de control ( IoC ) e Inyección de dependencia ( DI ) mientras que ApplicationContext proporciona funciones avanzadas .

Un BeanFactory está representado por la interfaz " org.springframework.beans.factory " Donde BeanFactory, para el que hay múltiples implementaciones.

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

DIFERENCIA

  1. BeanFactory instancia el bean cuando llamas al método getBean () mientras ApplicationContext instancia el bean Singleton cuando se inicia el contenedor, no espera que getBean () ser llamado.

  2. BeanFactory no brinda soporte para la internacionalización, pero ApplicationContext lo brinda.

  3. Otra diferencia entre BeanFactory vs ApplicationContext es la capacidad de publicar eventos en beans que están registrados como oyentes.

  4. Una de las implementaciones populares de la interfaz BeanFactory es XMLBeanFactory , mientras que una de las implementaciones populares de la interfaz ApplicationContext es ClassPathXmlApplicationContext .

  5. Si está utilizando el cableado automático y está utilizando BeanFactory , deberá registrar AutoWiredBeanPostProcessor utilizando la API que puede configurar en XML si está utilizando ApplicationContext . En resumen, BeanFactory está bien para pruebas y uso no productivo, pero ApplicationContext es una implementación de contenedor más rica en funciones y debe ser favorecida sobre BeanFactory

  6. BeanFactory por defecto es compatible con Lazy carga y ApplicationContext por defecto es compatible con Agresivo cargando.

La diferencia entre BeanFactory y ApplicationContext son los siguientes:

  1. BeanFactory usa una inicialización diferida pero ApplicationContext usa una inicialización ansiosa. En el caso de BeanFactory, el bean se crea cuando se llama al método getBeans (), pero el bean se crea por adelantado en el caso de ApplicationContext cuando se crea el objeto ApplicationContext.
  2. BeanFactory proporciona explícitamente un objeto de recurso utilizando la sintaxis pero ApplicationContext crea y administra objetos de recurso por sí mismo.
  3. BeanFactory no admite la internacionalización pero ApplicationContext admite la internacionalización.
  4. Con BeanFactory, la inyección de dependencia basada en anotaciones no es compatible pero la inyección de dependencia basada en anotaciones es compatible con ApplicationContext.

Uso de BeanFactory:

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

Uso de ApplicationContext:

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

Matriz de características de Bean Factory vs Contexto de aplicación procedente de documentos de primavera

 ingrese la descripción de la imagen aquí

Captura de pantalla de las características de BeanFacotry y ApplicationContext

Básicamente podemos crear un objeto contenedor de resorte de dos maneras

  1. usando BeatFactory
  2. usando ApplicationContext

ambas son las interfaces

usando clases de implementación podemos crear objetos para el contenedor de primavera

llegando a las diferencias

BeanFactory

  1. No admite la inyección de dependencia basada en anotaciones.

  2. No es compatible con I18N

  3. Por defecto es compatible con la carga lenta

  4. no permite configurar a múltiples archivos de configuración.

ej: BeanFactory context = new XmlBeanFactory (nuevo Recurso (" applicationContext.xml "));

ApplicationContext

  1. Inyección de dependencia basada en anotaciones de soporte.-@Autowired, @PreDestroy

  2. Soporte I18N

  3. su Por defecto soporta carga agresiva.

  4. permite configurar múltiples archivos de configuración.

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

a. Una diferencia entre la fábrica de beans y el contexto de la aplicación es que el anterior solo instancia el bean cuando se llama al método getBean () mientras que ApplicationContext instancia el bean Singleton cuando se inicia el contenedor. No espera a que se llame a getBean.

b.

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

o

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

Puede usar uno o más archivos xml dependiendo de los requisitos de su proyecto. Como estoy aquí usando dos archivos xml, es decir, uno para detalles de configuración para clases de servicio y otro para clases de dao. Aquí ClassPathXmlApplicationContext es hijo de ApplicationContext.

c. BeanFactory Container es un contenedor básico, solo puede crear objetos e inyectar dependencias. Pero no podemos & # 8217; t adjuntar otros servicios como seguridad, transacciones, mensajes, etc. para proporcionar todos los servicios que tenemos que usar ApplicationContext Container.

d. BeanFactory no proporciona soporte para la internacionalización, es decir, i18n, pero ApplicationContext brinda soporte para ello.

e. BeanFactory Container no admite la función de AutoScanning (Inyección de dependencia basada en anotaciones de soporte), pero ApplicationContext Container sí lo admite.

f. Beanfactory Container no creará un objeto bean hasta el momento de la solicitud. Significa que Beanfactory Container carga frijoles perezosamente. Mientras ApplicationContext Container crea objetos de Singleton Bean en el momento de la carga solamente. Significa que hay una carga temprana.

g. Beanfactory Container admite solo dos ámbitos (singleton & Amp; prototype) de los beans. Pero ApplicationContext Container admite todo el alcance de beans.

Consulte este documento de 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 o ApplicationContext?

Use un ApplicationContext a menos que tenga una buena razón para no hacerlo.

Debido a que ApplicationContext incluye toda la funcionalidad de BeanFactory, generalmente se recomienda sobre BeanFactory, a excepción de algunas situaciones como en un Applet donde el consumo de memoria puede ser crítico y unos pocos kilobytes adicionales pueden hacer la diferencia. Sin embargo, para la mayoría de las aplicaciones y sistemas empresariales típicos, el ApplicationContext es lo que querrá usar. Spring 2.0 y posterior hace un uso intensivo del punto de extensión BeanPostProcessor (para efectuar proxy y así sucesivamente). Si usa solo un BeanFactory simple, una cantidad justa de soporte, como transacciones y AOP, no tendrá efecto, al menos no sin algunos pasos adicionales de su parte. Esta situación podría ser confusa porque en realidad no hay nada malo con la configuración.

ApplicationContext es un hermano mayor de BeanFactory y esto sería todo lo que se proporciona BeanFactory además de muchas otras cosas.

Además de las capacidades estándar del ciclo de vida org.springframework.beans.factory.BeanFactory, las implementaciones de ApplicationContext detectan y  invoque los beans ApplicationContextAware, así como los beans ResourceLoaderAware, ApplicationEventPublisherAware y MessageSourceAware.

En un escenario en tiempo real, la diferencia entre el contenedor Spring IOC Core (BeanFactory) y el contenedor Advanced J2EE (ApplicationContext) es la siguiente.

  1. BeanFactory creará objetos para los beans (es decir, para las clases POJO) mencionados en el archivo spring.xml (<bean></bean>) solo cuando llame al método .getBean (), pero mientras que ApplicationContext crea los objetos para todos los beans (<=> si su alcance no se menciona explícitamente como " Prototype ") configurados en spring.xml mientras se carga el archivo spring.xml.

  2. BeanFactory: (contenedor diferido porque crea los objetos para los beans solo cuando llama explícitamente desde el usuario / clase principal)

    /*
     * 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: (Contenedor ansioso por crear los objetos de todos los beans singleton mientras se carga el archivo spring.xml)

    ApplicationContext context = new ClassPathXmlApplicationContext("com/ioc/constructorDI/resources/spring.xml");
    
  3. Técnicamente, se recomienda usar ApplicationContext porque en aplicaciones en tiempo real, los objetos de bean se crearán mientras la aplicación se inicia en el servidor. Esto reduce el tiempo de respuesta para la solicitud del usuario ya que los objetos ya están disponibles para responder.

Creo que vale la pena mencionar que desde Spring 3, si desea crear una fábrica, también puede usar @configuration anotación combinada con la correcta @scope

@Configuration
public class MyFactory {

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

Su fábrica debe ser visible por el contenedor Spring usando @ComponentScan anotación o configuración xml

Artículo de ámbitos de frijol de primavera del sitio baeldung

use BeanFactory para aplicaciones que no sean web porque solo admite los campos de bean Singleton y Prototype.

Si bien el contenedor ApplicationContext admite todos los ámbitos de bean, debe usarlo para aplicaciones web.

En resumen:

El ApplicationContext incluye toda la funcionalidad de BeanFactory. Generalmente se recomienda usar el primero.

Hay algunas situaciones limitadas, como en una aplicación móvil, donde el consumo de memoria puede ser crítico.

En esos escenarios, puede ser justificable usar el BeanFactory más ligero. Sin embargo, en la mayoría de las aplicaciones empresariales, el ApplicationContext es lo que querrá usar.

Para más información, vea la publicación de mi blog:

Diferencia entre BeanFactory y ApplicationContext en Spring & # 8211 ; El blog java spring de lo básico

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top