手写最简版IOC 学习总结

总结

  1. IOC容器的本质是一个Map<Class,Object>
  2. Spring通过注解与反射对Bean进行实例化,并放到容器中

 

 

Code

 

package com.sc.bean;

public interface ApplicationContext {
    public Object getBean(Class clazz);
}

 

package com.sc.bean;

import com.sc.annotation.Bean;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class AnnotationApplicationContext implements ApplicationContext{

    private Map<Class,Object> beanFactory = new HashMap<>();
    private String rootPath;
    @Override
    public Object getBean(Class clazz) {
        return beanFactory.get(clazz);
    }

    /**
     * 有参构造,传递包路径,扫描包以及子包
     * @param basePackage
     */
    public AnnotationApplicationContext(String basePackage) throws IOException {
        // 获取包路径
        String packageDirName = basePackage.replaceAll("\\.","\\\\");
        // 获取包路径下的所有文件
        Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
        while(urls.hasMoreElements()){
            URL url = urls.nextElement();
            String filePath = URLDecoder.decode(url.getPath(), "UTF-8");
            rootPath = filePath.substring(0,filePath.length()-packageDirName.length());
            loadBean(new File(filePath));
        }

    }

    /**
     * 递归扫描包,将@Bean注解的类实例化,加到IOC容器
     * @param file
     */

    private void loadBean(File file) {
        // 判断file是否存在,若为空则退出递归
        if(!file.exists()){
            return;
        }
        if(file.isDirectory()){
            File[] files = file.listFiles();
            for(File f : files){
                loadBean(f);
            }
        }else{
            // 获取文件名
            String fileName = file.getName();
            // 获取文件后缀
            String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
            // 判断文件后缀是否为class
            if("class".equals(suffix)){
                String classFullName = getClassFullName(file, suffix);
                loadBeanByReflect(classFullName);
            }
        }
    }

    /**
     * 通过反射实例化指定的类
     * @param classFullName
     */
    private void loadBeanByReflect(String classFullName) {
        try {
            // 获取类
            Class<?> clazz = Class.forName(classFullName);
            // 判断类是否被注解
            if(clazz.getAnnotation(Bean.class) != null){
                // 实例化
                Object bean = clazz.newInstance();
                // 若clazz存在接口,则将接口作为key添加到beanFactory
                if(clazz.getInterfaces().length>0){
                    beanFactory.put(clazz.getInterfaces()[0],bean);
                }else{
                    beanFactory.put(clazz,bean);
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 截取字符串,获取类全名
     * @param file 文件名
     * @param suffix 后缀
     * @return 类全名
     */
    private String getClassFullName(File file, String suffix) {
        // 获取全类名   com.ayguigu.dao.Serivice
        String absolutePath = file.getAbsolutePath();
        String classFullName = absolutePath
                .substring(rootPath.length()-1,absolutePath.length()- suffix.length()-1)
                .replaceAll("\\\\","\\.");
        return classFullName;
    }
}

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring框架是一个非常庞大的框架,涵盖了很多的功能和模块。如果要手写一个简单版的Spring框架,我们可以从以下几个方面入手: 1. IOC容器 Spring框架的核心就是IOC容器。我们可以实现一个简单的IOC容器,通过注解或配置文件的方式来管理Bean。首先,我们需要定义一个Bean类,它包含了类名、类路径、是否单例等信息。然后,我们需要解析注解或配置文件,将所有的Bean信息存储到一个Map中。最后,在需要使用Bean的地方,我们可以通过Bean的名称从Map中获取Bean实例。 2. AOP Spring框架的另一个核心是AOP。AOP可以帮助我们实现各种各样的切面功能,例如事务管理、日志记录等。我们可以通过定义切点和切面来实现AOP。切点定义了哪些方法需要被代理,切面定义了具体的代理逻辑。我们可以使用JDK动态代理或者CGLIB动态代理来实现代理逻辑。 3. MVC Spring框架还提供了一个MVC模块来帮助我们实现Web应用程序。我们可以实现一个简单的DispatcherServlet来接收HTTP请求,并且根据请求路径和请求方法来调用相应的Controller方法。Controller方法可以返回一个ModelAndView对象,其中包含了响应页面的路径和数据模型。最后,我们可以使用模板引擎来渲染响应页面。 以上是实现一个简单版Spring框架的基本思路。当然,这只是一个简单的示例,实际上Spring框架还包括了很多其他的功能和模块,例如JDBC、ORM等。如果想要更深入地了解Spring框架,可以参考Spring官方文档或者相关书籍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值