仿写简单IOC

目录

TestController类:

UserService类:

 核心代码SpringIOC:

Autowired和Component注解

SpringIOCTest 类 

​编辑

总结:


TestController类:

@Component
public class TestController {

    @Autowired
    private UserService userService;

    public void test(){
     userService.addUser("我口袋只剩玫瑰一片","此行又山高路远");
    }
}

UserService类:

@Component
public class UserService {

    public void addUser(String a,String b){
        System.out.println(a);
        System.out.println(b);
    }
}

 核心代码SpringIOC:

public class SpringIOC {
    private List<String> beanNames;
    private List<String> filePaths;
    private String basePath;
    private String basePackage;

    private Map<String, Object> beans =new HashMap<>();
    /**
     * 扫描所有的文件信息信息,存到了 filePaths
     */
    private void scan() throws FileNotFoundException {
        File file = new File(basePath);
        filePaths = new ArrayList<>();
        if(file.exists()){
            Queue<File> queue = new LinkedList<>();
            queue.add(file);
            while(!queue.isEmpty()){
                File poll = queue.poll();
                if(poll == null){
                    continue;
                }
                if(poll.isDirectory()){
                    File[] files = poll.listFiles();
                    for (File f : files) {
                        queue.add(f);
                    }
                }else {
                    filePaths.add(poll.getPath());
                }
            }
        }else {
            throw new FileNotFoundException(basePath+" not found");
        }
       //将路径中所有的文件打印出来 filePaths.forEach(e-> System.out.println(e));
    }

    /**
     * 讲所有的.java结尾的 全限定名放到 beanNames
     */
    public void  initBeanNames(){
        for (String s : filePaths) {
            String replace = s.replace(basePath, "");
            if(replace.endsWith(".java")) {
                replace = replace.substring(0, replace.length()-5);
            }

            char[] chars = replace.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                if(chars[i]=='\\'){
                    chars[i] = '.';
                }
            }
            beanNames.add(basePackage+"."+new String(chars));
        }
        beanNames.forEach(System.out::println);
    }

    public void initBeans(){
        for (String beanName : beanNames) {
            try {
                Class<?> aClass = Class.forName(beanName);
                Annotation[] declaredAnnotations = aClass.getDeclaredAnnotations();
                for (Annotation declaredAnnotation : declaredAnnotations) {
                    if(declaredAnnotation instanceof Component){
                        //反射:
                        Object o = aClass.newInstance();
                        beans.put(aClass.getName(),o);
                    }
                }
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException 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) {
                    if(annotation instanceof Autowired){
                        //field 需要由我们来赋值
                        // 我们所持有的所有对象 在beans中
                        // 根据当前域中的类型的名字:反射
                        String name = field.getType().getName();
                        // 从beans 中获得对应的对象
                        Object o = beans.get(name);
                        field.setAccessible(true);
                        try {
                            field.set(entry.getValue(), o);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }

            }


        }
    }
    public Object getInstance(String beanName) {
        return beans.get(beanName);
    }
    private void initPath(){
        basePath="D:\\imitateIOC\\src\\main\\java\\com\\test\\springioc\\";
        basePackage="com.test.springioc";
    }

    public SpringIOC() {
        initPath();
        try {
            scan();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        beanNames= new ArrayList<>();
        initBeanNames();
    }
}

Autowired和Component注解

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



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

SpringIOCTest 类 

public class SpringIOCTest {

    @Test
    public void testIOC() throws FileNotFoundException {

        //创建IOC容器
        SpringIOC springIOC = new SpringIOC();
        //初始化容器
        springIOC.initBeans();
        //从容器中获得TestController对象
        TestController instance = (TestController) springIOC.getInstance(TestController.class.getName());
        //调用其方法
        instance.test();
    }
}

总结:

整个环境可以归纳为两个阶段:

第一阶段:处理字符串,获得到类权限的名

第二阶段:根据类权限名创建对应的对象(带有@Component的类才会创建对应的对象),然后再遍历访问我们创建好的对象,判断所有的域是否带有@Autowired,如果有就从Bean中取出对应的对象设置进去。

通篇我们没有写new TestController,new UserService这种代码,都是由反射创建的对象设置进来,这就是这篇代码的基本逻辑。

源码已上传gitee平台:

https://gitee.com/dont-live-in-the-past/copy-ioc.git


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值