仿写SpringIoc

1.SpringIoc简单注解

1.1 Autowired

package com.qcby.iocdemo1.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

1.2 Component

package com.qcby.iocdemo1.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

2.创建一个controller和一个UserService对象,为后面案例展示提供方便

2.1 controller

package com.qcby.iocdemo1.entity;

import com.qcby.iocdemo1.annotation.Autowired;
import com.qcby.iocdemo1.annotation.Component;

@Component
public class TestController {
    @Autowired
    private UserService userService;
    public void test(){
        userService.addUser("zhangsan",18);
    }
}

2.2 UserService

package com.qcby.iocdemo1.entity;

import com.qcby.iocdemo1.annotation.Component;

@Component
public class UserService {

    public void addUser(String name, int age) {
        System.out.println(name);
        System.out.println(age);
    }
}

3.Ioc实现类

package com.qcby.iocdemo1.ioc;

import com.qcby.iocdemo1.annotation.Autowired;
import com.qcby.iocdemo1.annotation.Component;
import jdk.nashorn.internal.ir.ContinueNode;
import org.springframework.objenesis.instantiator.basic.NewInstanceInstantiator;

import java.beans.Beans;
import java.io.File;
import java.io.FileNotFoundException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;

public class SpringIOC {
    private String basePath;
    private String basePackage;
    private List<String> beanNames;
    private List<String> filePaths;
    private Map<String, Object> beans = new HashMap<>();

    private void initPath() {
        //设置三个包所在文件夹的绝对路径
        basePath = "D:\\gitcode\\IocDemo1\\src\\main\\java\\com\\qcby\\iocdemo1\\";
        //设置包名
        basePackage = "com.qcby.iocdemo1";
    }

    private void scan() throws FileNotFoundException {
        //创建文件夹对象
        File file = new File(basePath);
        //filePaths集合放置的是文件的绝对路径
        filePaths = new ArrayList<>();
        if (file.exists()) {
            Queue<File> queue = new LinkedList<>();
            //放文件夹下的子文件夹及文件
            queue.add(file);
            while (!queue.isEmpty()) {
                File poll = queue.poll();
                //队首文件出队
                if (poll.isDirectory()) {
                    //判断是否为文件夹,如果是把文件夹里的子文件夹和文件放入队列
                    File[] files = poll.listFiles();
                    for (File file1 : files) {
                        queue.add(file1);
                    }
                } else {
                    filePaths.add(poll.getPath());
                    //如果是文件把文件的路径放入filepaths
                }
            }
        } else {
            throw new FileNotFoundException(basePath + "没有找到");
        }
    }

    private void initBeanNames() {
        for (String s : filePaths) {
            //遍历filepaths
            String replace = s.replace(basePath, "");
            //将每个的前缀变成"",变成相对路径
            if (replace.endsWith(".java")) {
                replace = replace.substring(0, replace.length() - 5);
                //文件名以.java结尾的文件,去掉后缀
            }
            char[] chars = replace.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                if (chars[i] == '\\') {
                    chars[i] = '.';
                }
            }
            //将文件路径的/变成.
            beanNames.add(basePackage + "." + new String(chars));
            //将路径以保命+文件相对路径的形式添加到路径集合中
        }
    }

    public void initBeans(){
        for (String beanName : beanNames) {
            try {
                Class<?> aClass = Class.forName(beanName);
                //通过路径获取每个类的对象
                Annotation[] declaredAnnotations = aClass.getDeclaredAnnotations();
                //获取每个对类的注解
                for (Annotation declaredAnnotation : declaredAnnotations) {
                    //遍历注解,找到注解为component的注解
                    if (declaredAnnotation instanceof Component) {
                        //有的话,把类对象转化为实例对象,按照路径:对象的形式加入beans集合中
                        Object o = aClass.newInstance();
                        beans.put(aClass.getName(), o);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        for (Map.Entry<String, Object> entry : beans.entrySet()) {
            //遍历每一个路径:对象的键值对
            Field[] declaredFields = entry.getValue().getClass().getDeclaredFields();
            //获取该类的属性对象
            for (Field field : declaredFields) {
                Annotation[] declaredAnnotations = field.getDeclaredAnnotations();
                //遍历属性对象,获取属性上的注解
                for (Annotation annotation : declaredAnnotations) {
                    //遍历注解,判断该注解是否为autowired
                    if (annotation instanceof Autowired) {
                        //获取该属性的类型的名称
                        String name = field.getType().getName();
                        //找到该数据类型的实例对象
                        Object o = beans.get(name);
                        field.setAccessible(true);
                        try {
                            //把实例对象放入该属性中
                            field.set(entry.getValue(), o);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
    public SpringIOC(){
        initPath();
        try {
            scan();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }
        beanNames=new ArrayList<>();
        initBeanNames();
    }
    public Object getInstance(String beanName){
        return beans.get(beanName);
    }
}

4.使用test测试

        SpringIOC springIOC=new SpringIOC();
        springIOC.initBeans();
        TestController instance = (TestController)springIOC.getInstance(TestController.class.getName());
        instance.test();

5.运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值