• 简单实现spring的set依赖注入


     Maven依赖:

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0modelVersion>
    6. <groupId>org.myspringframeworkgroupId>
    7. <artifactId>myspringartifactId>
    8. <version>1.0-SNAPSHOTversion>
    9. <packaging>jarpackaging>
    10. <properties>
    11. <maven.compiler.source>17maven.compiler.source>
    12. <maven.compiler.target>17maven.compiler.target>
    13. <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    14. properties>
    15. <dependencies>
    16. <dependency>
    17. <groupId>dom4jgroupId>
    18. <artifactId>dom4jartifactId>
    19. <version>1.1version>
    20. dependency>
    21. <dependency>
    22. <groupId>jaxengroupId>
    23. <artifactId>jaxenartifactId>
    24. <version>1.2.0version>
    25. dependency>
    26. <dependency>
    27. <groupId>junitgroupId>
    28. <artifactId>junitartifactId>
    29. <version>4.13.2version>
    30. <scope>testscope>
    31. dependency>
    32. dependencies>
    33. project>
    1. public interface ApplicationContext {
    2. /**
    3. * 根据bean的名字获取对应的bean对象
    4. * @param beanName myspring配置文件中bean标签的id
    5. * @return 对应的bean对象
    6. */
    7. T getBean(String beanName,Class type);
    8. Object getBean(String beanName);
    9. }
    1. public class ClassPathXmlApplicationContext implements ApplicationContext{
    2. // 对应一级缓存
    3. private Map singletonObject=new HashMap<>();
    4. /**
    5. * 解析myspring的配置文件,然后初始化所有的bean对象。
    6. * @param configLocation Spring配置文件的路径,注意,使用ClassPathXmlApplicationContext,配置文件应放在类路径中
    7. */
    8. public ClassPathXmlApplicationContext(String configLocation) {
    9. // 解析myspring.xml配置文件,实例化bean,把bean放到集合中
    10. try {
    11. // 获取一个解析器对象
    12. SAXReader saxReader=new SAXReader();
    13. // 获取所要读取的文件的输入流
    14. URL resource = ClassLoader.getSystemClassLoader().getResource(configLocation);
    15. // 获取文档对象
    16. Document document = saxReader.read(resource);
    17. // 获取指定标签 //bean 表示获得多个bean标签
    18. List beans = document.selectNodes("//bean");
    19. // 遍历所有的bean并放到集合中
    20. beans.forEach(new Consumer() {
    21. @Override
    22. public void accept(Object o) {
    23. //向下转型,拥有更丰富的方法
    24. Element element= (Element) o;
    25. //获取bean后,再获取属性值id和class 注:class是全类名
    26. String id = element.attributeValue("id");
    27. String className = element.attributeValue("class");
    28. try {
    29. //有了类名后,直接反射创建对象
    30. Class clazz= Class.forName(className);
    31. //获取无参构造方法
    32. Constructor declaredConstructor = clazz.getDeclaredConstructor();
    33. //创建对象并放到map中 进行曝光
    34. Object bean = declaredConstructor.newInstance();
    35. singletonObject.put(id,bean);
    36. } catch (Exception e) {
    37. e.printStackTrace();
    38. throw new RuntimeException(e);
    39. }
    40. }
    41. });
    42. // 进行set注入,为属性赋值
    43. //首先得获得标签,获取其中的属性name和value 或是 name和ref
    44. beans.forEach(new Consumer() {
    45. @Override
    46. public void accept(Object o) {
    47. try {
    48. //获取bean的id和className
    49. Element element= (Element) o;
    50. String className=element.attributeValue("class");
    51. String id=element.attributeValue("id");
    52. //获取 中的所有标签
    53. List properties = element.elements();
    54. //遍历该bean所有标签
    55. properties.forEach(new Consumer() {
    56. @Override
    57. public void accept(Object o) {
    58. Element property= (Element) o;
    59. String fieldName = property.attributeValue("name");
    60. String propertyValue = property.attributeValue("value");
    61. String ref = property.attributeValue("ref");
    62. try {
    63. //利用反射
    64. Object bean=singletonObject.get(id);
    65. //获取set()方法
    66. String setMethodName="set"+fieldName.toUpperCase().charAt(0)+fieldName.substring(1);
    67. //获取全限定类型名
    68. Class propertyType= bean.getClass().getDeclaredField(fieldName).getType();
    69. //如果所获取的方法有参数的话,需要加上参数类型
    70. Method setMethod = bean.getClass().getDeclaredMethod(setMethodName,propertyType);
    71. //获取bean的set方法
    72. if(propertyValue!=null){
    73. Object propertyVal=null;
    74. //对于基本数据类型,如果想要调用相应的set方法,必须知道类型是什么
    75. String propertyTypeSimpleName=propertyType.getSimpleName();
    76. switch (propertyTypeSimpleName) {
    77. case "byte": case "Byte":
    78. propertyVal = Byte.valueOf(propertyValue);
    79. break;
    80. case "short": case "Short":
    81. propertyVal = Short.valueOf(propertyValue);
    82. break;
    83. case "int": case "Integer":
    84. propertyVal = Integer.valueOf(propertyValue);
    85. break;
    86. case "long": case "Long":
    87. propertyVal = Long.valueOf(propertyValue);
    88. break;
    89. case "float": case "Float":
    90. propertyVal = Float.valueOf(propertyValue);
    91. break;
    92. case "double": case "Double":
    93. propertyVal = Double.valueOf(propertyValue);
    94. break;
    95. case "boolean": case "Boolean":
    96. propertyVal = Boolean.valueOf(propertyValue);
    97. break;
    98. case "char": case "Character":
    99. propertyVal = propertyValue.charAt(0);
    100. break;
    101. case "String":
    102. propertyVal = propertyValue;
    103. break;
    104. }
    105. setMethod.invoke(singletonObject.get(id), propertyVal);
    106. }else if(ref!=null){
    107. //这个简单,直接把所需要的曝光后的对象赋值给它就行。
    108. setMethod.invoke(bean,singletonObject.get(ref));
    109. }
    110. } catch (Exception e) {
    111. e.printStackTrace();
    112. }
    113. }
    114. });
    115. } catch (Exception e) {
    116. throw new RuntimeException(e);
    117. }
    118. }
    119. });
    120. }catch (Exception e){
    121. e.printStackTrace();
    122. }
    123. }
    124. // 加个泛型
    125. @Override
    126. public T getBean(String beanName,Class type) {
    127. return (T)singletonObject.get(beanName);
    128. }
    129. @Override
    130. public Object getBean(String beanName) {
    131. return singletonObject.get(beanName);
    132. }
    133. }

  • 相关阅读:
    Spring知识点总结-DX的笔记
    yocto bsp-开发人员指南
    带你读论文丨S&P21 Survivalism: Living-Off-The-Land 经典离地攻击
    MySQL锁与脏读、不可重复读、幻读详解
    软件设计——面向对象的七大原则
    Python async模块使用(杂文)
    C语言基础之负数是怎么存储的?(六十一)
    Android NDK 之CmakeList 笔记
    XMLHttpRequest的基本使用
    Linux怎么安装python3.8
  • 原文地址:https://blog.csdn.net/qq_64071349/article/details/133977215