spring - ejemplo - BeanFactory vs ApplicationContext
spring boot factory bean (20)
Spring proporciona dos tipos de contenedor IOC, uno es
XMLBeanFactory
y otro esApplicationContext
.
+---------------------------------------+-----------------+--------------------------------+
| | 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
Beans cargados a través de la ruta completa. -
ClassPathXmlApplicationContext
Beans cargados a través de CLASSPATH -
XMLWebApplicationContext
yAnnotationConfigWebApplicationContext
beans cargados a través del contexto de la aplicación web. -
AnnotationConfigApplicationContext
Cargando beans Spring desde la configuración basada en Annotation.
ejemplo:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
-
ApplicationContext
es el contenedor inicializado porContextLoaderListener
oContextLoaderServlet
definido en unweb.xml
yContextLoaderPlugin
definido enstruts-config.xml
.
Soy bastante nuevo en Spring Framework, he estado jugando con él y juntando algunas aplicaciones de ejemplo con el propósito de evaluar Spring MVC para su uso en un próximo proyecto de la compañía. Hasta el momento, realmente me gusta lo que veo en Spring MVC, parece muy fácil de usar y te anima a escribir clases que sean muy amigables con las pruebas de unidad.
Solo como un ejercicio, estoy escribiendo un método principal para uno de mis proyectos de prueba / muestra. Una cosa de la que no estoy BeanFactory
es de las diferencias exactas entre BeanFactory
y ApplicationContext
, ¿cuál es el adecuado para usar en qué condiciones?
Entiendo que ApplicationContext
extiende BeanFactory
, pero si solo estoy escribiendo un método principal simple, ¿necesito la funcionalidad adicional que proporciona ApplicationContext
? ¿Y exactamente qué tipo de funcionalidad adicional proporciona ApplicationContext
?
Además de responder "qué debo usar en un método main ()", ¿existen estándares o pautas en cuanto a qué implementación debería usar en tal escenario? ¿Debería escribir mi método main () para que dependa de la configuración del bean / aplicación 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 necesiten ApplicationContext
?
Gracias por cualquier ayuda. Sé que muchas de estas preguntas probablemente se responden en el manual de referencia, pero me cuesta mucho encontrar un desglose claro de estas dos interfaces y las ventajas y desventajas de cada una sin leer el manual con un peine de dientes finos.
ApplicationContext
es la forma más preferida queBeanFactory
En las nuevas versiones de Spring,
BeanFactory
se reemplaza conApplicationContext
. Pero todavía existeBeanFactory
para compatibilidad con versiones anteriores-
ApplicationContext extends BeanFactory
y tiene los siguientes beneficios- Soporta internacionalización para mensajes de texto.
- Soporta la publicación de eventos a los oyentes registrados.
- Acceso a los recursos como URLs y archivos.
ApplicationContext es un hermano mayor de BeanFactory y esto es todo lo que BeanFactory ofrece y muchas otras cosas.
Además de las capacidades estándar de ciclo de vida org.springframework.beans.factory.BeanFactory, las implementaciones de ApplicationContext detectan e invocan los beans ApplicationContextAware, así como los beans ResourceLoaderAware, ApplicationEventPublisherAware y MessageSourceAware.
Básicamente podemos crear el objeto contenedor de primavera de dos maneras.
- utilizando BeatFactory
- utilizando ApplicationContext
ambas son las interfaces
Usando clases de implementación podemos crear objeto para contenedor de primavera.
llegando a las diferencias
BeanFactory
No es compatible con la Inyección de dependencia basada en anotación.
No soporta I18N
Por defecto es compatible con la carga perezosa.
no permite configurar múltiples archivos de configuración.
ej .: BeanFactory context = new XmlBeanFactory (new Resource ("applicationContext.xml"));
AplicaciónContexto
Compatibilidad basada en anotación Injection.-@Autowired, @PreDestroy
Apoyo I18N
Es por defecto el soporte de carga agregada.
Permite configurar múltiples archivos de configuración.
ex:
ApplicationContext context = new ClasspathXmlApplicationContext ("applicationContext.xml");
Consulte este documento de Spring Docs:
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, excepto en algunas situaciones, como en un Applet donde el consumo de memoria puede ser crítico y algunos kilobytes adicionales pueden hacer una diferencia. Sin embargo, para la mayoría de las aplicaciones y sistemas empresariales típicos, ApplicationContext es lo que querrá usar. Spring 2.0 y versiones posteriores hacen un uso intensivo del punto de extensión BeanPostProcessor (para efectuar proxies y así sucesivamente). Si solo usa un BeanFactory simple, una cantidad considerable de soporte, como transacciones y AOP, no entrarán en vigencia, al menos no sin algunos pasos adicionales de su parte. Esta situación podría ser confusa porque nada está realmente mal con la configuración.
Creo que es mejor usar siempre ApplicationContext, a menos que esté en un entorno móvil como ya lo dijo alguien más. ApplicationContext tiene más funciones y definitivamente desea utilizar PostProcessors como RequiredAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor y CommonAnnotationBeanPostProcessor, que le ayudará a simplificar sus archivos de configuración de Spring, y podrá utilizar anotaciones como @Required.Posestación .
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 post procesadores, o el otro esquema para agregar consejos transaccionales, ya tendrá un ApplicationContext y no necesitará cambiar ningún código.
Si está escribiendo una aplicación independiente, cargue ApplicationContext en su método principal, use un ClassPathXmlApplicationContext y obtenga el bean principal e invoque su ejecución () (o cualquier otro método) para iniciar su aplicación. Si está escribiendo una aplicación web, use ContextLoaderListener en web.xml para que cree ApplicationContext y luego pueda obtenerla de 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 ApplicationContext al enumerar todos los archivos en el constructor (o al enumerarlos en el parámetro de contexto para ContextLoaderListener), o simplemente puede cargar un archivo de configuración principal que tiene declaraciones de importación. Puede importar un archivo de configuración de Spring a otro archivo de configuración de Spring usando <import resource = "otherfile.xml" /> que es muy útil cuando crea mediante programación el ApplicationContext en el método principal y carga solo un archivo de configuración de Spring.
Creo que vale la pena mencionar que desde Spring 3, si desea crear una fábrica, también puede usar la anotación @configuration
combinada con el @scope
apropiado
@Configuration
public class MyFactory {
@Bean
@Scope("prototype")
public MyClass create() {
return new MyClass();
}
}
Su fábrica debe ser visible por el contenedor Spring utilizando la anotación @ComponentScan
o la configuración xml
Artículo de alcances de frijol de primavera del sitio baeldung
En resumen:
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, se puede justificar el uso de BeanFactory más ligero. Sin embargo, en la mayoría de las aplicaciones empresariales, lo que querrá usar es ApplicationContext .
Más sobre:
Diferencia entre BeanFactory y ApplicationContext en Spring - El blog de java spring desde lo básico
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 las 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 quiere que sus beans sean conscientes de Spring, puede hacer que implementen BeanFactoryAware y / o ApplicationContextAware para eso, de modo que pueda usar BeanFactory o ApplicationContext y elegir qué interfaz implementar.
En un escenario en tiempo real, la diferencia entre el contenedor Spring Core IOC (BeanFactory) y el contenedor Advanced J2EE (ApplicationContext) es la siguiente.
BeanFactory creará objetos para los beans (es decir, para las clases de POJO) mencionados en el archivo spring.xml (
<bean></bean>
) solo cuando llama al método .getBean (), pero mientras que ApplicationContext crea los objetos para todos los beans (<bean></bean>
si su alcance no se menciona explícitamente como "Prototype") configurado en el archivo spring.xml mientras se carga el archivo spring.xml.BeanFactory: (contenedor perezoso porque crea los objetos para los beans solo cuando se 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 Eager debido a la creación de los objetos de todos los beans de singleton mientras se carga el archivo spring.xml)
ApplicationContext context = new ClassPathXmlApplicationContext("com/ioc/constructorDI/resources/spring.xml");
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 propio servidor. Esto reduce el tiempo de respuesta para la solicitud del usuario ya que los objetos ya están disponibles para responder.
Las diferencias entre BeanFactory y ApplicationContext son las siguientes:
- BeanFactory usa inicialización perezosa pero ApplicationContext usa inicialización impaciente. En el caso de BeanFactory, el bean se crea cuando llama al método getBeans (), pero el bean se crea por adelantado en el caso de ApplicationContext cuando se crea el objeto ApplicationContext.
- BeanFactory proporciona explícitamente un objeto de recurso utilizando la sintaxis, pero ApplicationContext crea y administra los objetos de recursos por su cuenta.
- BeanFactory no admite la internacionalización, pero ApplicationContext admite la internacionalización.
- Con BeanFactory no se admite la inyección de dependencias basada en anotaciones, pero ApplicationContext admite la inyección de dependencias basada en anotaciones.
Utilizando BeanFactory:
BeanFactory beanfactory = new XMLBeanFactory(new FileSystemResource("spring.xml")); Triangle triangle =(Triangle)beanFactory.getBean("triangle");
Utilizando ApplicationContext:
ApplicationContext context = new ClassPathXMLApplicationContext("spring.xml") Triangle triangle =(Triangle)beanFactory.getBean("triangle");
Los documentos de primavera son excelentes en esto: 3.8.1. ¿BeanFactory o ApplicationContext? . Tienen una tabla con una comparación, voy a publicar un fragmento de código:
Fábrica de Frijoles
- Instanciación / cableado de frijol
Contexto de aplicación
- Instanciación / cableado de frijol
- Registro automático de BeanPostProcessor
- Registro automático de BeanFactoryPostProcessor
- Conveniente acceso a MessageSource (para i18n)
- Publicación ApplicationEvent
Por lo tanto, si necesita alguno de los puntos presentados en el lado del contexto de la aplicación, debe usar ApplicationContext.
Matriz de funciones de Bean Factory vs Contexto de aplicación procedente de Spring Docs
Captura de pantalla de características de BeanFacotry y ApplicationContext
Para agregar a lo que Miguel Ping respondió, aquí hay otra sección de la documentación que también responde a esto:
Versión corta: use un ApplicationContext a menos que tenga una buena razón para no hacerlo. Para aquellos de ustedes que están buscando un poco más de profundidad en cuanto al ''pero por qué'' de la recomendación anterior, continúen leyendo.
(publicando esto para los futuros novatos de primavera que puedan leer esta pregunta)
Para mí, la principal diferencia para elegir BeanFactory
sobre ApplicationContext
parece ser que ApplicationContext
creará una instancia previa de todos los beans. De los documentos de primavera :
Spring establece las propiedades y resuelve las dependencias lo más tarde posible, cuando el bean se crea realmente. Esto significa que un contenedor de Spring que se ha cargado correctamente puede generar más tarde una excepción cuando solicite un objeto si hay un problema al crear ese objeto o una de sus dependencias. Por ejemplo, el bean lanza una excepción como resultado de una propiedad faltante o no válida. Esta visibilidad potencialmente retardada de algunos problemas de configuración es la razón por la cual las implementaciones de ApplicationContext pre-instancian en forma predeterminada los beans singleton. Al costo de tiempo y memoria inicial para crear estos beans antes de que realmente sean necesarios, descubre problemas de configuración cuando se crea el ApplicationContext, no más tarde. Aún puede anular este comportamiento predeterminado para que los beans singleton se inicien de forma perezosa, en lugar de crear una instancia previa.
Dado esto, 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 alguien me corrige si me equivoco, BeanFactory
no admite la configuración de classpath
XML. Así que BeanFactory
y ApplicationContext
proporcionan una característica crucial que yo quería, pero ninguno de los dos lo hizo.
Por lo que puedo decir, la nota en la documentación sobre la anulación del comportamiento de instanciación predeterminado tiene lugar en la configuración, y es por bean, por lo que no puedo establecer el atributo "lazy-init" en el archivo XML o estoy pegado manteniendo una versión de la misma para la prueba y una para la implementación.
Lo que terminé haciendo fue extender ClassPathXmlApplicationContext
para cargar beans de forma perezosa para usarlos en pruebas como las siguientes:
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);
}
}
}
a. Una diferencia entre la fábrica de beans y el contexto de la aplicación es que la instancia anterior solo ejemplifica el bean cuando llama al método getBean (), mientras que ApplicationContext crea una instancia del bean Singleton cuando se inicia el contenedor, no espera a que se llame a getBean.
segundo.
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, otro para clases dao. Aquí ClassPathXmlApplicationContext es hijo de ApplicationContext.
do. BeanFactory Container es un contenedor básico, solo puede crear objetos e inyectar dependencias. Pero no podemos adjuntar otros servicios como seguridad, transacciones, mensajería, etc. para proporcionar todos los servicios que tenemos para usar ApplicationContext Container.
re. BeanFactory no proporciona soporte para la internacionalización, es decir, i18n, pero ApplicationContext proporciona soporte para la internacionalización.
mi. BeanFactory Container no admite la función de AutoScanning (Inyección de dependencia basada en anotación de soporte), pero ApplicationContext Container es compatible.
F. Beanfactory Container no creará un objeto bean hasta el momento de la solicitud. Significa que Beanfactory Container carga los frijoles perezosamente. Mientras que ApplicationContext Container crea objetos de bean Singleton en el momento de la carga solamente. Significa que hay carga temprana.
sol. Beanfactory Container admite solo dos ámbitos (singleton y prototipo) de los beans. Pero ApplicationContext Container soporta todo el alcance de los beans.
use BeanFactory para aplicaciones que no sean web, ya que solo admite Singleton y Prototype bean-scopes.
Si bien el contenedor ApplicationContext admite todos los ámbitos de bean, por lo que debe usarlo para aplicaciones web.
ApplicationContext: carga los beans de resorte configurados en el archivo de configuración de spring, y administra el ciclo de vida de los beans de spring como y cuando se inicia el contenedor. No esperará hasta que se llame a getBean ("springbeanref") .
BeanFactory Carga frijoles configurados en el archivo de configuración de resortes, administra el ciclo de vida del frijol de resorte cuando llamamos a getBean ("springbeanref") . Por lo tanto, cuando llamamos a getBean ("springbeanref") en el momento en que comienza el ciclo de vida del frijol de primavera .
BeanFactory y ApplicationContext son formas de obtener beans de su contenedor Spring IOC , pero todavía hay algunas diferencias.
BeanFactory es el contenedor real que crea instancias, configura y administra una cantidad de beans. Estos beans suelen colaborar entre sí y, por lo tanto, tienen dependencias entre sí. Estas dependencias se reflejan en los datos de configuración utilizados por BeanFactory.
BeanFactory y ApplicationContext son interfaces de Java y ApplicationContext extiende BeanFactory. Ambos son configuración utilizando archivos de configuración XML. En resumen, BeanFactory proporciona características 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 cual hay múltiples implementaciones.
ClassPathResource resource = new ClassPathResource("appConfig.xml");
XmlBeanFactory factory = new XmlBeanFactory(resource);
DIFERENCIA
BeanFactory crea una instancia del bean cuando llama al método getBean () , mientras que ApplicationContext crea una instancia del bean Singleton cuando se inicia el contenedor, no espera a que se llame a getBean ().
BeanFactory no proporciona soporte para la internacionalización, pero ApplicationContext proporciona soporte para ello.
Otra diferencia entre BeanFactory y ApplicationContext es la capacidad de publicar eventos en beans que están registrados como oyentes.
Una de las implementaciones populares de la interfaz de BeanFactory es XMLBeanFactory, mientras que una de las implementaciones populares de la interfaz de ApplicationContext es ClassPathXmlApplicationContext .
Si está utilizando el cableado automático y BeanFactory , entonces necesita registrar AutoWiredBeanPostProcessor utilizando la API que puede configurar en XML si está utilizando ApplicationContext . En resumen, BeanFactory está bien para pruebas y no para uso en producción, pero ApplicationContext es una implementación de contenedor más rica en características y debe ser favorecida sobre BeanFactory
BeanFactory por defecto es compatible con la carga diferida y ApplicationContext por defecto admite la carga agregada .
- BeanFactory: no es compatible con la inyección de dependencia basada en anotación.
- ApplicationContext: soporte de Annotation dependency Injection. - @ Autowired, @PreDestroy
- BeanFactory: No soporta
- ApplicationContext: los contextos de la aplicación pueden publicar eventos en beans registrados como oyentes
- BeanFactory: no admite la forma de acceder al paquete de mensajes (internacionalización (I18N)
- ApplicationContext: mensajes de internacionalización de soporte (I18N).
- BeanFactory: No soporta.
- ApplicationContext: soporta muchos servicios empresariales como el acceso JNDI, la integración EJB, la comunicación remota.
- BeanFactory: Por defecto, su soporte Lazy loading
- ApplicationContext: Por defecto es compatible con la carga agregada.