简单仿写SpringIOC

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

项目目录结构

 Autowired

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}

Component

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
}

HydService

@Component
public class HydService {

    public void test() {
        System.out.println("成功调用service方法");
    }
}

HydIOC

public class HydIOC {
//        包名加类名(没有.java后缀)
        private List<String> bean_names;
//        全类路径
        private List<String> file_paths;
//        main方法路径
        private String base_path;
//        包名
        private String base_package;
//        放类实例
        private Map<String,Object> beans = new HashMap<>();


        public HydIOC(String basepath, String basepackage) {

//                处理basepath和basepackage
//                basepath:/D:/javacode/myIOC/out/production/myIOC/com/hyd/springIOC/
//                处理成:D:\javacode\myIOC\out\production\myIOC\com\hyd\springIOC\
                basepath=basepath.substring(1).replace("/","\\");
                this.base_path=basepath;
//                形如:com.hyd.springIOC
                this.base_package=basepackage;
                try{
//                        扫描文件
                        scan_files();
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                }
//                获取实例的名称集合
                this.bean_names = new ArrayList<>();
                init_bean_names();

        }

        /**
         * 生成bean_names
         */
        private void init_bean_names() {
                for (String file_path : this.file_paths) {
                        file_path = file_path.replace(this.base_path,"");
                        if (file_path.endsWith(".class")){
                                file_path = file_path.substring(0,file_path.length()-6);
                        }
                        String bean_name = this.base_package + "." + file_path.replaceAll(Matcher.quoteReplacement(File.separator),".");
                        this.bean_names.add(bean_name);
                }
        }

        /**
         * 扫描当前路径下的文件
         */
        private void scan_files() throws FileNotFoundException {
                File file = new File(this.base_path);
                this.file_paths = new ArrayList<>();
                if (file.exists()){
//                        新建一个用来处理文件的队列
                        LinkedList<File> file_lists = new LinkedList<>();
                        file_lists.add(file);
                        while (!file_lists.isEmpty()){
//                                取出一个文件进行处理
                                File temp_file = file_lists.removeFirst();
                                if (temp_file!=null){
//                                        判断是否为文件夹
                                        if (temp_file.isDirectory()){
//                                                是文件夹就把其子文件放到队列中
                                                File[] files = temp_file.listFiles();
                                                for (File file1 : files) {
                                                        file_lists.add(file1);
                                                }
                                        }else {
//                                                不是文件夹就把文件路径放到路径列表中
                                                this.file_paths.add(temp_file.getPath());
                                        }
                                }else {
                                        continue;
                                }
                        }
                }else {
                        throw new FileNotFoundException("找不到"+this.base_path+"路径下的文件");
                }
        }

        public void initBeans() {
                for (String bean_name : this.bean_names) {
                        try{
                                Class<?> cl = Class.forName(bean_name);
//                                获取类的全部注解
                                Annotation[] annotations = cl.getDeclaredAnnotations();
//                                判断所有注解汇中是否有Component注解
                                for (Annotation annotation : annotations) {
                                        if (annotation instanceof Component){
//                                                有就把实例化对象放到map中
                                                Object o = cl.newInstance();
                                                this.beans.put(cl.getName(),o);
                                        }
                                }
                        } catch (ClassNotFoundException e) {
                                e.printStackTrace();
                        } catch (InstantiationException e) {
                                e.printStackTrace();
                        } catch (IllegalAccessException e) {
                                e.printStackTrace();
                        }
                }

//                处理Autowired注解的注入
//                遍历map所有的实例
                for (Map.Entry<String, Object> entry : this.beans.entrySet()) {
//                        获取实例中的域
                        Field[] fields = entry.getValue().getClass().getDeclaredFields();
//                        遍历所有的域
                        for (Field field : fields) {
//                                获取域的注解
                                Annotation[] annotations = field.getDeclaredAnnotations();
//                                遍历注解
                                for (Annotation annotation : annotations) {
//                                        判断注解中是否有Autowired注解
                                        if (annotation instanceof Autowired){
//                                                filed样例值:private com.hyd.springIOC.service.HydService com.hyd.springIOC.controller.HydController.hydService
//                                                name样例值:com.hyd.springIOC.service.HydService
                                                String name = field.getType().getName();
//                                                从map中获取对应的实例
                                                Object o = this.beans.get(name);
//                                                设置字段为可访问状态
                                                field.setAccessible(true);
                                                try {
//                                                        将获取的对象实例 o 注入到当前字段所属的对象实例中
                                                        field.set(entry.getValue(),o);
                                                } catch (IllegalAccessException e) {
                                                        e.printStackTrace();
                                                }
                                        }
                                }
                        }
                }
        }

//        对外获取实例的方法
        public Object getInstance(String name) {
                return this.beans.get(name);
        }
}

HydController

@Component
public class HydController {
    @Autowired
    private HydService hydService;

    public void hydtest(){
        hydService.test();
    }
}

Main

public class Main {
    public static void main(String[] args) {

        String basepath = Main.class.getResource("").getPath();
//        获取Main的包名
        String basepackage = Main.class.getPackage().getName();
        HydIOC hydIOC = new HydIOC(basepath,basepackage);
        hydIOC.initBeans();
        HydController hydController = (HydController) hydIOC.getInstance(HydController.class.getName());
        hydController.hydtest();
    }
}

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

跳转仿写MVC

相关推荐

  1. 仿Vue的{{}}语法

    2024-07-10 12:46:02       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 12:46:02       99 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 12:46:02       107 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 12:46:02       90 阅读
  4. Python语言-面向对象

    2024-07-10 12:46:02       98 阅读

热门阅读

  1. element ui form添加校验规则

    2024-07-10 12:46:02       25 阅读
  2. splice方法的使用#Vue3

    2024-07-10 12:46:02       24 阅读
  3. 使用Dockerfile和ENTRYPOINT运行Python 3脚本

    2024-07-10 12:46:02       26 阅读
  4. 黑龙江等保测评对中小企业成本效益分析

    2024-07-10 12:46:02       21 阅读
  5. 6、Redis系统-数据结构-01-String

    2024-07-10 12:46:02       30 阅读
  6. STM32学习和实践笔记(39):I2C EEPROM实验

    2024-07-10 12:46:02       25 阅读
  7. Python面试题:请解释什么是反射(reflection)?

    2024-07-10 12:46:02       23 阅读
  8. Rudolf and k Bridges——Codeforces Round 933 (Div. 3) E

    2024-07-10 12:46:02       25 阅读