当前位置:   article > 正文

简单仿写SpringIOC

简单仿写SpringIOC

gitee地址(需要自取)ioc_Imitation: 简单仿写IOC (gitee.com) 

项目目录结构

 Autowired

  1. @Target(ElementType.FIELD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface Autowired {
  4. }

Component

  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface Component {
  4. }

HydService

  1. @Component
  2. public class HydService {
  3. public void test() {
  4. System.out.println("成功调用service方法");
  5. }
  6. }

HydIOC

  1. public class HydIOC {
  2. // 包名加类名(没有.java后缀)
  3. private List<String> bean_names;
  4. // 全类路径
  5. private List<String> file_paths;
  6. // main方法路径
  7. private String base_path;
  8. // 包名
  9. private String base_package;
  10. // 放类实例
  11. private Map<String,Object> beans = new HashMap<>();
  12. public HydIOC(String basepath, String basepackage) {
  13. // 处理basepath和basepackage
  14. // basepath:/D:/javacode/myIOC/out/production/myIOC/com/hyd/springIOC/
  15. // 处理成:D:\javacode\myIOC\out\production\myIOC\com\hyd\springIOC\
  16. basepath=basepath.substring(1).replace("/","\\");
  17. this.base_path=basepath;
  18. // 形如:com.hyd.springIOC
  19. this.base_package=basepackage;
  20. try{
  21. // 扫描文件
  22. scan_files();
  23. } catch (FileNotFoundException e) {
  24. e.printStackTrace();
  25. }
  26. // 获取实例的名称集合
  27. this.bean_names = new ArrayList<>();
  28. init_bean_names();
  29. }
  30. /**
  31. * 生成bean_names
  32. */
  33. private void init_bean_names() {
  34. for (String file_path : this.file_paths) {
  35. file_path = file_path.replace(this.base_path,"");
  36. if (file_path.endsWith(".class")){
  37. file_path = file_path.substring(0,file_path.length()-6);
  38. }
  39. String bean_name = this.base_package + "." + file_path.replaceAll(Matcher.quoteReplacement(File.separator),".");
  40. this.bean_names.add(bean_name);
  41. }
  42. }
  43. /**
  44. * 扫描当前路径下的文件
  45. */
  46. private void scan_files() throws FileNotFoundException {
  47. File file = new File(this.base_path);
  48. this.file_paths = new ArrayList<>();
  49. if (file.exists()){
  50. // 新建一个用来处理文件的队列
  51. LinkedList<File> file_lists = new LinkedList<>();
  52. file_lists.add(file);
  53. while (!file_lists.isEmpty()){
  54. // 取出一个文件进行处理
  55. File temp_file = file_lists.removeFirst();
  56. if (temp_file!=null){
  57. // 判断是否为文件夹
  58. if (temp_file.isDirectory()){
  59. // 是文件夹就把其子文件放到队列中
  60. File[] files = temp_file.listFiles();
  61. for (File file1 : files) {
  62. file_lists.add(file1);
  63. }
  64. }else {
  65. // 不是文件夹就把文件路径放到路径列表中
  66. this.file_paths.add(temp_file.getPath());
  67. }
  68. }else {
  69. continue;
  70. }
  71. }
  72. }else {
  73. throw new FileNotFoundException("找不到"+this.base_path+"路径下的文件");
  74. }
  75. }
  76. public void initBeans() {
  77. for (String bean_name : this.bean_names) {
  78. try{
  79. Class<?> cl = Class.forName(bean_name);
  80. // 获取类的全部注解
  81. Annotation[] annotations = cl.getDeclaredAnnotations();
  82. // 判断所有注解汇中是否有Component注解
  83. for (Annotation annotation : annotations) {
  84. if (annotation instanceof Component){
  85. // 有就把实例化对象放到map中
  86. Object o = cl.newInstance();
  87. this.beans.put(cl.getName(),o);
  88. }
  89. }
  90. } catch (ClassNotFoundException e) {
  91. e.printStackTrace();
  92. } catch (InstantiationException e) {
  93. e.printStackTrace();
  94. } catch (IllegalAccessException e) {
  95. e.printStackTrace();
  96. }
  97. }
  98. // 处理Autowired注解的注入
  99. // 遍历map所有的实例
  100. for (Map.Entry<String, Object> entry : this.beans.entrySet()) {
  101. // 获取实例中的域
  102. Field[] fields = entry.getValue().getClass().getDeclaredFields();
  103. // 遍历所有的域
  104. for (Field field : fields) {
  105. // 获取域的注解
  106. Annotation[] annotations = field.getDeclaredAnnotations();
  107. // 遍历注解
  108. for (Annotation annotation : annotations) {
  109. // 判断注解中是否有Autowired注解
  110. if (annotation instanceof Autowired){
  111. // filed样例值:private com.hyd.springIOC.service.HydService com.hyd.springIOC.controller.HydController.hydService
  112. // name样例值:com.hyd.springIOC.service.HydService
  113. String name = field.getType().getName();
  114. // 从map中获取对应的实例
  115. Object o = this.beans.get(name);
  116. // 设置字段为可访问状态
  117. field.setAccessible(true);
  118. try {
  119. // 将获取的对象实例 o 注入到当前字段所属的对象实例中
  120. field.set(entry.getValue(),o);
  121. } catch (IllegalAccessException e) {
  122. e.printStackTrace();
  123. }
  124. }
  125. }
  126. }
  127. }
  128. }
  129. // 对外获取实例的方法
  130. public Object getInstance(String name) {
  131. return this.beans.get(name);
  132. }
  133. }

HydController

  1. @Component
  2. public class HydController {
  3. @Autowired
  4. private HydService hydService;
  5. public void hydtest(){
  6. hydService.test();
  7. }
  8. }

Main

  1. public class Main {
  2. public static void main(String[] args) {
  3. String basepath = Main.class.getResource("").getPath();
  4. // 获取Main的包名
  5. String basepackage = Main.class.getPackage().getName();
  6. HydIOC hydIOC = new HydIOC(basepath,basepackage);
  7. hydIOC.initBeans();
  8. HydController hydController = (HydController) hydIOC.getInstance(HydController.class.getName());
  9. hydController.hydtest();
  10. }
  11. }

整体与之前的仿写MVC的思路相差不大,不做过多描述

跳转仿写MVC

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/822124
推荐阅读
相关标签
  

闽ICP备14008679号