从山寨Spring中学习Spring IOC原理-XML-Constructor

2024-01-10 10:08

本文主要是介绍从山寨Spring中学习Spring IOC原理-XML-Constructor,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

上一篇【从山寨Spring中学习Spring IOC原理-XML-Setter】我们完成了对Spring中Setter方法的山寨,那么这次就要改造一下我们的程序,让其满足使用构造方法注入。进入之前希望有条件的读者,下手把笔者贴出来的代码敲一遍,或者复制一遍在编译器里跟踪运行一下。这样每一步取了什么值,为什么这样写,就会更加明白了。更多Spring内容进入【Spring解读系列目录】。

修改程序

如果是使用构造方法进行构建,那么就需要在UserServiceImpl使用构造方法传递UserDao进去,修改代码为:

public class UserServiceImpl implements UserService {private UserDao userDao;@Overridepublic void find() {System.out.println("UserServiceImpl find()");userDao.query();}public void setUserDao(UserDao userDao) {this.userDao = userDao;}public UserServiceImpl(UserDao userDao) {  //创建构造方法this.userDao = userDao;}
}

同时我们的配置文件也要修改,为了简化代码,只让有一个构造方法。

<?xml version="1.0" encoding="UTF-8"?>
<beans><bean id="dao" class="com.demo.dao.UserDaoImpl"></bean><bean id="service" class="com.demo.service.UserServiceImpl"><!--假设只有一个构造方法--><constructor-arg name="userDao" ref="dao"></constructor-arg></bean>
</beans>

最终修改的大头就落在了BeanFactory上,为了更加清楚,我们重构一个类BeanFactoryCon:

public class BeanFactoryCon {Map<String, Object> map=new HashMap<>();public BeanFactoryCon(String xml) {parseXml(xml);}public void parseXml(String xml){String path=this.getClass().getResource("/").getPath()+xml;File file=new File(path);SAXReader reader = new SAXReader();try {Document document = reader.read(file);Element elementRoot=document.getRootElement();//拿取xml中元素的内容for (Iterator<Element> itFirst = elementRoot.elementIterator(); itFirst.hasNext();) {Element elementFirstChild = itFirst.next();//取到id值Attribute attribute=elementFirstChild.attribute("id");String beanName=attribute.getValue();//取到类全名Attribute attribute2=elementFirstChild.attribute("class");String clazzName=attribute2.getValue();//获取标签中的类全名Class clazz=Class.forName(clazzName);//当我们写了构造方法的时候,默认的构造方法就不存在了,所以不能直接newInstance()构建实例,而应该使用标签里的构造标签Object object=null;//维护依赖关系,找到依赖关系:判断是否有属性,然后判断属性是否有对应的constructor-arg//  如果有则注入,所以每循环到一个bean就要拿出子标签for (Iterator<Element> itSecond = elementFirstChild.elementIterator(); itSecond.hasNext();) {Element elementSecondChild =itSecond.next();if (elementSecondChild.getName().equals("constructor-arg")){//把map中存的UserDao对象拿出来String refValue=elementSecondChild.attribute("ref").getValue();Object injectObj=map.get(refValue);//把UserDao对象构造为一个类Class injectObjClazz=injectObj.getClass();String nameValue=elementSecondChild.attribute("name").getValue();//拿到属性类型,为了创建构造方法Field field=clazz.getDeclaredField(nameValue);//根据属性类型创建构造方法对象,这里也可以通过实现的接口去构造Constructor constructor=clazz.getConstructor(field.getType());//clazz.getConstructor(injectObjClazz.getInterfaces()[0]);//使用构造方法对象把UserDao对象注入进去。object=constructor.newInstance(injectObj);}}if(object==null){//没有子标签,意味着没有依赖所以new出来object=clazz.newInstance();}map.put(beanName,object);}System.out.println(map.toString());} catch (Exception e) {e.printStackTrace();}}public Object getBean(String bean){return map.get(bean);}
}

修改完毕以后,修改Test类,运行测试:

public class Test {public static void main(String[] args) {BeanFactoryCon beanFactoryCon=new BeanFactoryCon("spring.xml");UserService service= (UserService) beanFactoryCon.getBean("service");service.find();}
}
运行结果:
UserServiceImpl find()
UserDaoImpl query 1

总结

在对上个程序进行简单的修改以后,我们就完成了容器基于构造方法的注入,其实通过这些例子的构造,大体也能猜出Spring源码到底的怎么写的,只是那些大神们的思维更加的严谨,更加的详实。目前已经注入没有问题了,既然要山寨Spring,就不能少了Spring的自动注入。所以下一篇【从山寨Spring中学习Spring IOC原理-byType自动装配】我们就会模拟一个Spring自动注入的过程。

这篇关于从山寨Spring中学习Spring IOC原理-XML-Constructor的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/590428

相关文章

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

Python xmltodict实现简化XML数据处理

《Pythonxmltodict实现简化XML数据处理》Python社区为提供了xmltodict库,它专为简化XML与Python数据结构的转换而设计,本文主要来为大家介绍一下如何使用xmltod... 目录一、引言二、XMLtodict介绍设计理念适用场景三、功能参数与属性1、parse函数2、unpa

Spring MVC如何设置响应

《SpringMVC如何设置响应》本文介绍了如何在Spring框架中设置响应,并通过不同的注解返回静态页面、HTML片段和JSON数据,此外,还讲解了如何设置响应的状态码和Header... 目录1. 返回静态页面1.1 Spring 默认扫描路径1.2 @RestController2. 返回 html2

关于Maven中pom.xml文件配置详解

《关于Maven中pom.xml文件配置详解》pom.xml是Maven项目的核心配置文件,它描述了项目的结构、依赖关系、构建配置等信息,通过合理配置pom.xml,可以提高项目的可维护性和构建效率... 目录1. POM文件的基本结构1.1 项目基本信息2. 项目属性2.1 引用属性3. 项目依赖4. 构

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去