En la clase Java, un gran hombre llamado Rod Johnson descubrió que el desarrollo inicial de nivel empresarial de Java estaba en un estado caótico.
Entonces decidió escribir una infraestructura general que pudiera resolver problemas.
Porque cree firmemente que la programación orientada a la interfaz puede minimizar los cambios, pero también facilitar la expansión y el cambio. Entonces, escribió la siguiente interfaz.
Lo primero que debe crear en un estado caótico es la madre de todos los objetos, la fábrica de frijoles, y con él, puede obtener todos los objetos y atributos que sufre, es decir, en primer lugar, Gaia: la madre de la tierra.
Con la Madre BeanFactory original, Johnson pensó, ¿qué pasaría si quisiera obtener un conjunto de objetos de frijoles en lugar de solo uno o varios? Además, ¿qué pasa si el hijo de la madre también quiere dar a luz a una pareja? Por lo tanto, Johnson creó ListableBeanFactory para operar un conjunto de objetos de frijoles. Por ejemplo, GetBeAnsofType puede obtener un conjunto de frijoles del mismo tipo basado en él; creado JerárquicoBeanFactory para resolver los problemas jerárquicos de múltiples factory de frijoles, como GetParentBeanFactory puede obtener la fábrica principal de BeanFactory.
Esta Factory se usa en última instancia en una aplicación, por lo que la Factory de Bean debe tener la capacidad de moverse en una aplicación. En BeanFactory, solo necesita considerar comportamientos relacionados con los frijoles, como cómo obtener frijoles, tipo de frijoles, etc.; Y si desea brindarles habilidades en la aplicación, debe considerar más, como el nombre de la aplicación, el tiempo de inicio, la identificación, etc. comportamientos y atributos relacionados con la aplicación en sí, por lo que Johnson pensó en crear una aplicación context. Johnson pensó que esta aplicación contexto debe poder hacer muchas cosas, y debe poder manejar información de texto parametrizada e internacionalizada, por lo que agrega la interfaz Messageurce; Debe ser capaz de publicar eventos para desacoplar componentes, por lo que tiene la interfaz ApplicationVentPublisher; Debe poder obtener archivos de recursos, por lo que tiene la interfaz ResourcePatterNResolver; Debe ser capaz de tener diferentes objetos de procesamiento en diferentes entornos, por lo que tiene la interfaz con capacidad para el entorno.
ApplicationContext hereda todas estas interfaces.
Pero lo más importante es que tanto BeanFactory como ApplicationContext deben tener capacidades configurables, por lo que existen subinterfaces configurables BeanFactory y ConfigurAableApplicationContext; Además, la Web era una tendencia muy importante en ese momento, y era un poco única en comparación con otras aplicaciones, por lo que necesitaba obtener servletContext, por lo que había WebApplicationContext.
Hasta ahora, Johnson ha estado pensando abstracto sobre el comportamiento de la interfaz y no los ha implementado en detalle.
Al observar el beanfactory y la aplicación creado, Johnson se dio cuenta de que el trabajo del día estaba lejos de terminar porque no había una solución real para hacer que todo el sistema funcionara, por lo que Johnson comenzó a pensar en cómo implementarlos.
Lo primero que piensa Johoson es en qué capacidades debería tener esta implementación. Por supuesto, debemos incluir el AutoWirecapableBeanFactory, ListableBeanFactory y ConfigurableBeanFactory mencionado anteriormente. Por lo tanto, se creó la Factory ConfigurAlListable. En segundo lugar, se deben considerar varias habilidades para los objetos de frijoles, una es la capacidad de alias; El segundo es la capacidad de salvar objetos singleton; El tercero es la capacidad de almacenar en caché; Se implementan en la clase de SimpleAliasRegistry, la clase predeterminada de BeanBeanRegistry y la clase FactoryBeanRegistrySupport, respectivamente.
Finalmente, se creó defaultListableBeanFactory, que es el prototipo de todas las fábricas del COI en primavera y es el primer niño real de BeanFactory. Este niño es muy importante y se ha convertido en la base para la creación independiente de contenedores del COI. Si se extiende y usa, la mayoría de ellos se heredan o se usan en combinación.
Si desea inicializar una factury de faushlistableBeanFactory, puede usar el siguiente código
ClasspathResource res = new ClassPathResource ("ApplicationContext.xml"); DefaultListableBeanFactory F = new DefaultListableBeanFactory (); XMLBeanDefinitionReader r = new XMLBeanDefinitionReader (f); R.LoadBeanDefinitions (Res); A continuación, Johnson pensó que BeanFactory tiene una implementación predeterminada relativamente completa, entonces, ¿qué pasa con la aplicaciónContext? Entonces, Johnson creó incansablemente tres importantes implementaciones de aplicaciones: FileSystemXMLApPlicationContext, ClassPathXMLApPlicationContext, AnnotationConfigWebApplicationContext (de hecho, hay muchos más, como manejar portlets y manejo de redes)
Lo primero que considera Johnson es cómo hacer el proceso de inicio de primavera. Debe colocarse en un nivel relativamente abstracto para que todas las clases en el nivel inferior puedan reutilizarse. Por lo tanto, implementó el ConfigureBlApplicationContext utilizando un AbstractApplicationContext. También hay una función muy importante, es decir, cargar un archivo en forma de un recurso, que requiere abstraer el recurso en una clase de recursos y abstraer la implementación específica del recurso de posicionamiento al resumenCelloader. AbstractApplicationContext también necesita heredar el defaultresourceloader para proporcionar esta función. AbstractApplicationContext completó todo el proceso de inicio (Dios lo arregló para completarse al día siguiente), pero no administró BeanFactory. Por lo tanto, su subclase AbtrtractrefreshableApplicationContext hace esto específicamente, la implementación de refreshBeanFactory, closeBeanFactory, getBeanFactory maneja específicamente el ciclo de vida de la factory de beanfactory, pero AbstractrefreshableApplicationContext todavía no carga todos los frijoles configurados. Dónde cargar los recursos configurados, en realidad va a la subclase inferior para hacerlo, como FileSystemXMLAplaPlicationContext, que es leer un XML ApplicationContext en el sistema de archivos; ClassPathXMLApplicationContext es para leer esta aplicaciónContext en la ruta de carga de clase. AnnotationConfigWebApplicationContext Carga los frijoles de la anotación del archivo de clase, y el escaneo de resorte comienza a partir de ahora.
Al ver que se había establecido el marco principal, Johnson se quedó dormido de satisfacción con una sonrisa.
El primer día, Johnson completó un marco general de primavera.
El segundo día, Johnson se estaba preparando para lidiar con los problemas anteriores. Por ejemplo, el proceso de inicialización del contenedor de Spring. Como se muestra en la figura, Johnson divide este proceso en muchos subprocesos, que están trabajando en torno al gran objetivo de cargar frijoles.
Este proceso se coloca en el método de actualización en el abstractAplicationContext. El código es el siguiente: Johnson divide el proceso de actualización en muchos subprocesos, y estos subprocesos están en el mismo nivel abstracto. Esta forma de escribir es dar a las generaciones futuras un modelo a seguir.
public void refresh () lanza BeanSexception, IllegalStateException {Synchronized (this.StartUpshutdownMonitor) {// Prepare este contexto para refrescarse. prepararerefresh (); // Dígale a la subclase que actualice la fábrica de frijoles internos. ConfiguableListableBeanFactory beanFactory = obtenFreshBeanFactory (); // Prepare la fábrica de bean para su uso en este contexto. PrepareBeanFactory (BeanFactory); Pruebe {// permite el procesamiento posterior de la fábrica de bean en subclases de contexto. PostProcessBeanFactory (BeanFactory); // Invocar procesadores de fábrica registrados como frijoles en el contexto. InvokeBeanFactoryPostProcessors (BeanFactory); // registra procesadores de frijoles que interceptan la creación de frijoles. RegisterBeanPostProcessors (BeanFactory); // Inicializar la fuente de mensajes para este contexto. initMessageReurce (); // Inicializar el mulstaster de eventos para este contexto. initApplicationEventMultCaster (); // Inicializar otros frijoles especiales en subclases de contexto específicos. onrefresh (); // Verifique los frijoles del oyente y regídalos. RegisterListeners (); // Instanciar todos los singletons restantes (innato de inicio). finkbeanFactoryInitialization (beanFactory); // Último paso: publique el evento correspondiente. finkeRefresh (); } Catch (Beansexception ex) {// Destruir singletons ya creados para evitar recursos colgantes. DestroyBeans (); // Restablecer la bandera 'activa'. cancelRefresh (ex); // Propague la excepción a la persona que llama. tirar ex; }}} Si lo mira en un nivel superior, estos procesos realmente giran en torno a varios aspectos: 1. Actualizar el ciclo de vida; 2. Inicialización y preparación de BeanFactory; 3. Genere y registre Beandefinition; 4. Postprocesador de BeanFactory; 5. Establezca mensajes, eventos y oyentes.
1. Ciclo de vida refrescante
PrepareFresh, este proceso registra principalmente el registro e indica que Spring ha comenzado, inicializa los recursos de propiedad (como inicializar algunos recursos en Serlvet) y verificar los recursos de propiedades (como solo escribir clave sin valor).
OnRefresh, el propósito es proporcionar algunas aplicaciones especiales de texto, para que puedan expandirse durante el proceso de actualización. La mayor parte del uso actual es establecer el tema para el contexto de la aplicación Servlet
EnfletRefresh, hacer un trabajo de finalización, como inicializar el ciclo de vida, el procesador de la publicación, el evento de publicación finalización para actualizar, etc.
CancheRefresh, cambia principalmente el estado actual a no activo cuando ocurre una excepción.
2. Inicialización y preparación de BeanFactory
Johnson piensa que deberíamos dejar que el beanfactory se cargue y registre el bean de manera transparente cuando se inicializa, por lo que mi encapsulación es muy exitosa para el mundo exterior, por lo que este paso en realidad hace muchas cosas. La siguiente figura omite muchos pasos y enumera solo puntos clave.
AbstractApplicationContext llamará a RefreshBeanFactory. Primero verificará y cerrará la Factory existente, luego creará una nueva Factory y luego usará esta fábrica para cargar todas las Definiciones de Bean.
Entre ellos, LoadBeanDefinitions se entregará a subclases para diferentes implementaciones. Por ejemplo, AbstractXMLApPlicationContext se lee principalmente a través de XML; AnnotationConfigWebApplicationContext Implementation llamará al escáner para escanear los frijoles en la clase.
3. Generar y registrar beandefinition
Después de analizar la configuración XML, el método ParsedefaultElement del valor predeterminado de DefinitionDocumentReader realizará el procesamiento correspondiente basado en los elementos en el XML. Entre ellos, cuando se encuentre con un elemento de frijol, finalmente se llamará al método de Infinición de registro en BeandefinitionReaderUtils. El parámetro aprobado en este método es BeanDefinitionRegistry, que en realidad devuelve el método de registro de registro de la definición de defaultBeanFactory para registrar beandefinition (defaultListableBeanFactory implementa beandefinitionRegistry).
4. Postprocesador de Beanfactory
El postprocesador de BeanFactory es una forma proporcionada por la primavera para permitir que sus subclases sean flexibles. Hay 2 pasos en la primavera: PostProcessBeanFactory, InvokeBeanFactoryPostProcessors. RegisterBeanPostProcessors instanciar y llamar a todos los procesadores de beanpost, que se utilizan para expandir el frijol antes y después de la inicialización de frijoles.
5. Configurar mensajes, eventos y oyentes
Establezca la fuente de mensaje predeterminada en DelegatingMessageSource. Si ya hay un MessageSource en la fábrica, use este Messageurce. El evento Multicastaster es SimpleApplicationEventMultCaster. Si ya hay una aplicación EVENTMULTASTER en la fábrica, use esta aplicación EventMultCaster y registre a todos los oyentes de aplicaciones para recibir eventos.
Messagesurce es un método importante para archivos de recursos internacionales. Spring admite fuentes de mensajes en ApplicationContext.
Spring proporciona la implementación predeterminada de Messagesurce, utilizando java.util.resourceBundle para extraer mensajes. Spring puede acceder directamente al mensaje desde ApplicationContext.getMessage () configurando un bean con una ID especial como Messagesurce y configurando el nombre del archivo de i18n. Si está en JSP, también puede acceder al mensaje a través de la etiqueta Spring: Mensaje.
Evento: los eventos son un mecanismo de desacoplamiento relativamente importante. Spring lo ha introducido en el núcleo AplicationContext. Su principio es relativamente simple. Por un lado, el generador de eventos puede enviar eventos; Por otro lado, parece que el oyente del evento puede responder a los eventos. La implementación específica básicamente tiene una colección de oyentes de eventos en el generador y "registrarse" (es decir, unirse) a todos los oyentes a esta colección de oyentes de eventos.
En Spring, ApplicationContext se usa como generador de eventos, los mistas de aplicaciones se utilizan como colección de oyentes y ApplicationVentMulticaster se utiliza para publicar eventos.
Varios pasos para publicar un evento:
Subscripción: inicialmente addapplicationListener a la colección de oyentes.
Publicar: ApplicationContext hereda el ApplicationEventPublisher, implementando así PublisheVent. Este método primero atravesará la colección AplicationListeners de este aplicaciones, llame a OnApplicationEvent para cada oyente, por lo que cada oyente será notificado; Después de completar este paso, se publicará el mismo evento para todos los muebles de aplicaciones de ApplicationContext Parent.
La publicación de eventos es muy común. No solo nuestras propias aplicaciones pueden usar esta publicación de eventos, sino que el marco de Spring en sí también está utilizando la publicación de eventos. Aquí hay algunas aplicaciones de eventos en primavera:
El ContextreFreshedEvent se publicará en Finishrefresh para indicar que la actualización termina y notifica al oyente. En el ApplicationContext, los métodos Start and Stop publicarán eventos que indican el contexto de inicio o finalización.
Después de que Johnson creó el marco principal y el proceso de operación de Spring, descubrió que Spring proporciona muchos lugares de expansión flexibles. Entonces Johnson se está preparando para anunciar este uso flexible de expansión en el tercer día.
1. Beanpostprocessor. BeanPostProcessor proporciona una interfaz de extensión después de completar la creación de frijoles. Cuando necesite procesar algo de los frijoles después de que se creen, BeanPostProcessor es el método preferido.
2. Consciente. El frijol inyectado necesita conocer algunas partes de su contenedor. Spring completa las devoluciones de llamada a través de ADACE, como Beannameaware, que permite que Bean conozca su nombre. BeanFactoryaware puede permitir que Bean entienda BeanFactory, ApplicationContextAware, que permite que Bean opere ApplicationContext. De esta manera, el frijol inyectado con primavera puede hacer una gama más amplia de cosas.
Para la extensión de BeanPostProcessor, Spring en sí tiene un ejemplo de cómo identificar un frijol consciente. Los frijoles conscientes son frijoles relativamente especiales, y la primavera requiere algunos atributos adicionales. Entonces, ¿cómo se utilizará Spring para el proceso de inyección? De hecho, Spring no lo escribe en el proceso de procesamiento central, sino que lo coló en el ApplicationContextAwarProcessor, el BeanPostProcessor y finalmente InvokeaWareInterfaces para determinar el tipo de bean e inyectar atributos correspondientes. Este enfoque utiliza BeanPostProcessor para completar otro uso extendido, que es realmente excelente.
Private void InvokeawareInterfaces (objeto bean) {if (bean instanceOf ADAK) {if (bean instanceOf EnvironmentAware) {((ambienteee) bean) .setenVironment (this.applicationContext.getEnvironment ()); } if (bean instanceo de increddedValueReSolverAware) {((IncedDedValueReSolveraWare). } if (bean instanceof resourcelOaaderaware) {((resourCeCelsoaderaware) bean) .setResourCelOader (this.ApplicationContext); } if (bean instanceOf ApplicationEventPublisheraAware) {((ApplicationEventPublisheraAware) Bean) .SetApplicationEventPublisher (this.ApplicationContext); } if (bean instanceOf MessagesOurCeaware) {((MessagesOurCeaware) Bean) .SetMessageSource (this.ApplicationContext); } if (bean instanceOf ApplicationContextAware) {((ApplicationContextAware) Bean) .SetApplicationContext (this.ApplicationContext); }}}Hay más reglas para usar ABSOK. Por ejemplo, el siguiente código puede percibir el ApplicationContext. Después de que Spring crea este bean, inyectará el ApplicationContext, por lo que podemos usar este contexto para completar la publicación de eventos.
public class Hellobean implementa ApplicationContextAware {private ApplicationContext ApplicationContext; cadena privada helloword = "¡Hola! World!"; public void setApplicationContext (contexto de applicationContext) {this.applicationContext = context; } public void Sethelloword (String Helloword) {this.helloword = helloword; } public String getHelloword () {applicationContext.PublisheVent (new PropertyGetteDeVent ("[" + Helloword + "] se gotta")); regresar helloword; }} 3. BeanFactoryPostProcessor, este postprocesador generalmente se usa para manejar la interfaz extendida creada por BeanFactory. Un ejemplo es el siguiente. Después de inyectar este frijol, imprimirá automáticamente el número de frijoles inyectados después de la creación de BeanFactory:
La clase pública BeanCounter implementa beanFactoryPostProcessor {@Override public void PostProcessBeanFactory (configuableListableBeanFactory BeanFactory) lanza Beansexception {system.out.println (beanFactory.getBeanDefinitionCount ()); }} 4. Factorybean. FactoryBean es un frijol especial, que permite la inyección en contenedores de primavera y generando frijoles reales, por lo que se puede definir de esta manera. FactoryBean es un frijol, que tiene la capacidad de proporcionar frijoles. Lo siguiente comienza con la llamada de fábrica y habla sobre cómo Spring usa este frijol.
Para distinguir entre frijoles ordinarios y fábricas, la primavera también debe tener un proceso de juzgarlos y manejarlos especialmente. Este proceso se encuentra en el getObjectForBeanInstance de Abstract BeanFactory
Objeto protegido getObjectForBeanInstance (Object BeanInstance, Nombre de cadena, String BeanName, RootBeanDefinition MBD) {// No permita que llame Código intente desreferir la fábrica si el bean no es una fábrica. if (beanFactoryUtilS.IsfActoryDeReference (name) &&! (beanInstance } // Ahora tenemos la instancia de Bean, que puede ser un frijol normal o una fábrica. // Si se trata de una fábrica, la usamos para crear una instancia de Bean, a menos que la persona que llama // realmente quiera una referencia a la fábrica. if (! (beaninstance } Objeto objeto = nulo; if (mbd == null) {object = getCachedObjectForFactoryBean (beanName); } if (object == null) {// Devuelve la instancia de Bean desde fábrica. FactoryBean <?> Factory = (factoryBean <?>) BeanInstance; // Caches Objeto obtenido de FactoryBean si es un singleton. if (mbd == null && contieneBeanDefinition (beanName)) {mbd = getMergedLocalBeanDefinition (beanName); } boolean sintética = (mbd! = null && mbd.issynthetic ()); objeto = getObjectFromFactoryBean (Factory, BeanName ,! Synthetic); } objeto de retorno; } Se puede ver que si se trata de un frijol ordinario, se devolverá directamente, y si es una fábrica, la llamada final llamará a fábrica.getObject para devolver el objeto específico. Si piensa en toda la primavera como una fábrica abstracta y al producir frijoles abstractos, FactoryBean es una fábrica específica que produce los objetos que necesita.
Hay muchos usos de FactoryBean en primavera. Para dar un ejemplo relativamente común, al integrar la Factory de Session de Hibernate, LobalsessionFactoryBean generalmente se inyecta, pero esta Factory de Session en realidad no es un frijol ordinario. Se puede producir simplemente inyectándolo en el archivo de configuración. Tiene muchas piezas personalizadas, por lo que Spring hace de este frijol una fábrica de fábrica y controla su objeto de producción.