Desarrollo manual: programa simple basado en configuración Spring XML
Directorio de artículos
Este artículo lo llevará a escribir un contenedor Spring simple. Al leer el archivo de configuración beans.xml, puede obtener el primer objeto JavaBean:Monster, asignar un valor al objeto, colocarlo en el contenedor y generar la información del objeto.
Primero revisemos cuando usamos Spring, obtenemos ClassPathXmlApplicationContext
el contenedor, el contenedor lee automáticamente el archivo de configuración beans.xml, obtenemos el objeto ioc
a través del método del contenedor y generamos el objeto.getBean
Todo lo que necesitas hacer ahora es:
- Para implementar un contenedor ioc usted mismo, la premisa es implementar uno propio
ClassPathXmlApplicationContext()
; ClassPathXmlApplicationContext()
Proporcione un método getBean().
Análisis de pensamiento@
Aquí nos centramos en ClassPathXmlApplicationContext()
el proceso de implementación específico:
- Defina una
ioc
asignaciónConcurrentHashMap
que almacene la identificación del nombre del objeto y el objeto. - Cree un constructor y coloque todas las siguientes operaciones en este constructor.
- Utilice
xml
tecnología de análisisdom4j
parabeans.xml
leer la información del archivo y obtener los valores de los atributos de la información del nodo. - Crea objetos usando la reflexión.
- Coloque el objeto
ioc
en - proporcionar un
getBean
método
Cuando utilice la tecnología de análisis xml dom4j
para leer la información en el archivo beans.xml y obtener los valores de atributo de la información del nodo, primero debe obtener la ruta al archivo beans.xml. La ruta aquí se refiere a la ruta donde se encuentran los archivos compilados del proyecto, es decir, target
la ruta en el directorio de trabajo. Nuestro archivo beans.xml se coloca resource
en el directorio. Después de la compilación, se ejecutará en el directorio de destino / clases. , entonces aquí el directorio que dom4j
leemos debe ser D:/Java/JavaProjects/spring-context-v1/target/classes/
: la ruta de trabajo completa del archivo debe ser D:/Java/JavaProjects/spring-context-v1/target/classes/beans.xml
;
String path = this.getClass().getResource("/").getPath();
// System.out.println("path="+path);
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(path + iocBeanXmlFile));
Después de obtener document
el objeto del documento, obtuvimos todo el contenido en beans.xml. En este momento, obtuvimos el nodo raíz y luego obtuvimos el primer objeto bean de la etiqueta de bean a través del nodo raíz, los atributos en la etiqueta de bean y el Se pueden obtener valores. Puede obtener la ruta de clases completa a través del atributo de clase de la etiqueta del bean. Una vez que obtenga la ruta de clases, puede crear un objeto mediante la reflexión. El tipo de este objeto es el objeto de su ruta de clases.
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(path + iocBeanXmlFile));
Element rootElement = document.getRootElement();
Element bean = (Element) rootElement.elements("bean").get(0);
String id = bean.attributeValue("id");
String classFullPath = bean.attributeValue("class");
System.out.println("id="+id);
System.out.println("classFullPath="+classFullPath);
List<Element> property = bean.elements("property");
String monsterId = property.get(0).attributeValue("value");
String name = property.get(1).attributeValue("value");
System.out.println("monsterId="+monsterId);
System.out.println("name="+name);
Solo los objetos creados a través de la reflexión pueden tener una estructura similar al objeto Monster. Podemos inyectar los valores de atributo del objeto bean extraídos de beans.xml en el objeto creado por nuestra reflexión y luego agregar este objeto a la colección ioc. .
Class<?> aClass = Class.forName(classFullPath);
Monster o = (Monster) aClass.newInstance();
o.setId(Integer.valueOf(monsterId));
o.setName(name);
ioc.put(id,o);
Finalmente, getBean
se proporciona un método para encontrar el objeto Monster asignado correspondiente en el contenedor ioc cuando se proporciona el monsterId.
public Object getBean(String id){
return ioc.get(id);
}
Finalmente, se realizó la imagen de arriba. Solo necesitamos configurar el objeto bean en el archivo xml y luego darle el nombre del archivo xml al LingHuApplication
contenedor para la inicialización para obtener un contenedor ioc. La esencia del contenedor ioc es una ConcurrentHashMap
. Internamente, la información de configuración del objeto bean se lee a través de dom4j, el objeto se crea mediante reflexión como classFullPath y la información de configuración del objeto bean se inyecta en el nuevo objeto. Este nuevo objeto se coloca en él ConcurrentHashMap
y getBean(String monsterId)
recorremos los métodos ConcurrentHashMap
para encontrar el nuevo objeto.
La importancia de hacer estas cosas es que separamos el trabajo de configuración y el trabajo comercial, y el tedioso trabajo de administración de objetos se completa a través del archivo de configuración, lo que reduce el acoplamiento del código y elimina el código comercial. Entonces, la esencia de la idea del contenedor de Spring es: ConcurrentHashMap
+Reflection crea objetos.
Código completo &:
Aplicación LingHu.java:
package com.linghu.spring.linghuapplication;
import com.linghu.spring.bean.Monster;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.context.annotation.ComponentScan;
import java.io.File;
import java.net.MalformedURLException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author
* @version 1.0
* * 1. 这个程序用于实现Spring的一个简单容器机制
* * 2. 后面我们还会详细的实现
* * 3. 这里我们实现如何将beans.xml文件进行解析,并生成对象,放入容器中
* * 4. 提供一个方法 getBean(id) 返回对应的对象
* * 5. 这里就是一个开胃小点心, 理解Spring容器的机制
*/
public class LingHuApplication {
private ConcurrentHashMap<String, Object> ioc =
new ConcurrentHashMap<>();
public LingHuApplication(String iocBeanXmlFile) throws MalformedURLException, DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException {
String path = this.getClass().getResource("/").getPath();
// System.out.println("path="+path);
//得到一个解析器
SAXReader saxReader = new SAXReader();
//老师的代码技巧->debug 看看document对象的属性
//分析了document对象的底层结构
Document document = saxReader.read(new File(path+iocBeanXmlFile));
//1. 得到rootElement, 你是OOP
Element rootElement = document.getRootElement();
//2. 得到第一个bean-monster01
Element bean = (Element) rootElement.elements("bean").get(0);
//获取到第一个bean-monster01的相关属性
String id = bean.attributeValue("id");
String classFullPath = bean.attributeValue("class");
List<Element> property = bean.elements("property");
System.out.println("id="+id);
System.out.println("classFullPath="+classFullPath);
//获取bean对象中的property属性值-id和name
String name = property.get(1).attributeValue("value");
String monsterId = property.get(0).attributeValue("value");
System.out.println("name="+name);
System.out.println("id="+monsterId);
//使用反射创建对象
Class<?> aClass = Class.forName(classFullPath);
//o对象就是monster对象
Monster o = (Monster) aClass.newInstance();
// System.out.println("o="+o);
o.setId(Integer.valueOf(monsterId));
o.setName(name);
//将创建好的对象放入到ioc对象中
ioc.put(id,o);
}
//提供一个getBean(id)返回对应的bean对象
public Object getBean(String id){
return ioc.get(id);
}
}
Gitee: "Desarrollo manual: programa simple basado en configuración Spring XML"