• SpringIOC容器Bean对象的实例化模拟


    思路:
    1. 定义 Bean ⼯⼚接⼝,提供获取 bean ⽅法
    2. 定义 Bean ⼯⼚接⼝实现类,解析配置⽂件,实例化Bean对象
    3. 实现获取 Bean ⽅法

    1、定义 Bean 属性对象

    1. package org.example.spring;
    2. /**
    3. * Bean属性对象:用来封装Spring配置文件中bean标签的id和class属性值
    4. */
    5. public class MyBean {
    6. private String id; //存放bean标签的id值
    7. private String clazz; //存放bean标签的class属性值
    8. public MyBean() {
    9. }
    10. public MyBean(String id, String clazz) {
    11. this.id = id;
    12. this.clazz = clazz;
    13. }
    14. public String getId() {
    15. return id;
    16. }
    17. public void setId(String id) {
    18. this.id = id;
    19. }
    20. public String getClazz() {
    21. return clazz;
    22. }
    23. public void setClazz(String clazz) {
    24. this.clazz = clazz;
    25. }
    26. }

    2、添加 dom4j和xpath依赖

    1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    3. <modelVersion>4.0.0modelVersion>
    4. <groupId>org.examplegroupId>
    5. <artifactId>spring02artifactId>
    6. <version>1.0-SNAPSHOTversion>
    7. <packaging>jarpackaging>
    8. <name>spring02name>
    9. <url>http://maven.apache.orgurl>
    10. <properties>
    11. <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    12. properties>
    13. <dependencies>
    14. <dependency>
    15. <groupId>junitgroupId>
    16. <artifactId>junitartifactId>
    17. <version>4.12version>
    18. <scope>testscope>
    19. dependency>
    20. <dependency>
    21. <groupId>dom4jgroupId>
    22. <artifactId>dom4jartifactId>
    23. <version>1.6.1version>
    24. dependency>
    25. <dependency>
    26. <groupId>jaxengroupId>
    27. <artifactId>jaxenartifactId>
    28. <version>1.1.6version>
    29. dependency>
    30. dependencies>
    31. project>

    3、准备自定义的spring配置文件

    1. "1.0" encoding="utf-8" ?>
    2. <beans>
    3. <bean id="userDao" class="org.example.service.UserDao">bean>
    4. <bean id="userService" class="org.example.service.UserService">bean>
    5. beans>

    4、定义 Bean 工厂接口

    1. package org.example.spring;
    2. /**
    3. * Bean工厂接口的定义
    4. */
    5. public interface MyFactory {
    6. //根据id属性值获取bean对象
    7. public Object getBean(String id);
    8. }

    5、定义 Bean 接口的实现类

    1. package org.example.spring;
    2. import org.dom4j.Document;
    3. import org.dom4j.Element;
    4. import org.dom4j.XPath;
    5. import org.dom4j.io.SAXReader;
    6. import java.net.URL;
    7. import java.util.ArrayList;
    8. import java.util.HashMap;
    9. import java.util.List;
    10. import java.util.Map;
    11. /**
    12. * 模拟Spring的实现
    13. * 1.通过有参构造方法获得对应的配置文件
    14. * 2.使用dom4j解析配置文件(spring配置文件),得到一个List集合(这个List集合存放了一系列bean标签的id和class属性值)
    15. * 3.通过反射机制创建对应的实例化对象并存入到一个Map集合中(遍历List集合,通过获取对应的class属性值,利用反射机制实例化对象)
    16. * 4.根据id值获取bean对象
    17. */
    18. public class MyClassPathXmlApplicationContext implements MyFactory{
    19. //存放从spring配置文件中获取到的bean标签的信息
    20. private List beanList;
    21. //使用Map集合存放实例化好的bean对象
    22. private Map beanMap = new HashMap<>();
    23. //1.通过有参构造方法获得对应的配置文件
    24. public MyClassPathXmlApplicationContext(String fileName) {
    25. //2.使用dom4j解析配置文件(spring配置文件),然后得到一个List集合(这个List集合存放了一系列bean标签的id和class属性值)
    26. this.parseXml(fileName);
    27. //3.通过反射机制创建对应的实例化对象并存入到一个Map集合中
    28. this.instanceBean();
    29. }
    30. /**
    31. * 通过反射机制创建对应的实例化对象并存入到一个Map集合中
    32. */
    33. private void instanceBean() {
    34. //1.判断对象集合是否为空,如果不为空则遍历集合,获取对应的id和class属性
    35. if (beanList != null && beanList.size()>0){
    36. for (MyBean bean:beanList){
    37. String id = bean.getId();
    38. String clazz = bean.getClazz();
    39. try {
    40. //2.通过反射机制根据类的全路径名实例化对象
    41. Object object = Class.forName(clazz).newInstance();
    42. //3.将对应的id和实例化好的bean对象放入Map集合中
    43. beanMap.put(id,object);
    44. }catch (Exception e){
    45. e.printStackTrace();
    46. }
    47. }
    48. }
    49. }
    50. /**
    51. * 使用dom4j解析spring配置文件,得到List集合
    52. * @param fileName
    53. */
    54. private void parseXml(String fileName) {
    55. //1.获取解析器
    56. SAXReader saxReader = new SAXReader();
    57. //2.获取配置文件的URL
    58. URL url = this.getClass().getClassLoader().getResource(fileName);
    59. try{
    60. //3.通过解析器解析spring配置文件
    61. Document document = saxReader.read(url);
    62. //4.通过xpath语法解析,获取beans标签下的所有bean标签
    63. XPath xPath = document.createXPath("beans/bean");
    64. //5.通过指定的解析语法解析文档对象,返回元素集合
    65. List elementList = xPath.selectNodes(document);
    66. //6.判断元素集合是否为空
    67. if (elementList != null && elementList.size()>0){
    68. //实例化List集合
    69. beanList = new ArrayList<>();
    70. //7.如果元素集合不为空,就遍历集合
    71. for (Element e:elementList){
    72. //8.获取bean标签元素的属性(id和class属性值)
    73. String id = e.attributeValue("id");
    74. String clazz = e.attributeValue("class");
    75. //9.获取MyBean对象,将id和class属性值设置到对象中,再将对象添加到List集合中
    76. MyBean myBean = new MyBean(id,clazz);
    77. beanList.add(myBean);
    78. }
    79. }
    80. }catch (Exception e){
    81. e.printStackTrace();
    82. }
    83. }
    84. /**
    85. * 通过id获取对应bean对象
    86. * @param id
    87. * @return
    88. */
    89. public Object getBean(String id) {
    90. Object object = beanMap.get(id);
    91. return object;
    92. }
    93. }

    6、测试自定义的IOC容器

    先定义用于测试的两个类:

    1. package org.example.dao;
    2. public class UserDao {
    3. public void test(){
    4. System.out.println("UserDao Test...");
    5. }
    6. }
    7. package org.example.service;
    8. public class UserService {
    9. public void test(){
    10. System.out.println("UserService Test...");
    11. }
    12. }

    编写测试程序: 

    1. package org.example;
    2. import org.example.dao.UserDao;
    3. import org.example.service.UserService;
    4. import org.example.spring.MyClassPathXmlApplicationContext;
    5. import org.example.spring.MyFactory;
    6. /**
    7. * Hello world!
    8. *
    9. */
    10. public class App
    11. {
    12. public static void main( String[] args )
    13. {
    14. //得到工厂的实现对象
    15. MyFactory factory = new MyClassPathXmlApplicationContext("spring.xml");
    16. //得到对应的实例化对象
    17. UserDao userDao = (UserDao)factory.getBean("userDao");
    18. userDao.test();
    19. UserService userService = (UserService)factory.getBean("userService");
    20. userService.test();
    21. }
    22. }

  • 相关阅读:
    Hadoop简介与集群配置
    java基础面试题 第四天
    快来跟我一起抢先看看未来世界的出行,体验未来城市吧~
    ViewPager2 PageTransformer
    HTML 基础
    vscode java 报错一例
    Easy3D文章目录汇总
    权威推荐!腾讯安全DDoS边缘安全产品获国际研究机构Omdia认可
    python使用Augmentor对图像分割数据集中原图和标签mask同时进行变换
    Win11安装最新Android studio时闪退
  • 原文地址:https://blog.csdn.net/m0_61925586/article/details/137997896