手写Spring框架

手写Spring框架

各位道友,我发现现在贼卷底层代码,看完源码发下几天后,额!!!我当时看了啥!

还是自己写个迷你的spring框架,这样印象更加深刻,上干货,代码仓库:https://gitee.com/smd_somin/SmdSpring.git

上面是我写的迷你版的spring框架,麻雀虽小,五脏俱全,主要包括下边的内容

  • 容器启动
  • BeanDefinition扫描
  • Bean声明周期
  • 单例与多例
  • 依赖注入
  • AOP
  • aware回调
  • 初始化
  • BeanPostProcessor(增强器)

下面是手写框架的过程和思路,仅供大家参考!!!

相信大家总会遇到这样问题,聊聊你理解的spring?

这个基本是100个技术,99个会遇到这个问题?我谈一下我得理解,仅供参考,我认为spring可以用两行表示

    //创建容器
    SmdApplicationContext context = new SmdApplicationContext(AppConfig.class);
    //获取对象
    UserInterface userService = (UserInterface) context.getBean("userService");

在这两行代码所牵连的内容其实就是spring的本质,对与bean的管理。

如果需要容器,那么我们需要有一个容器类,下面是手写spring容器的全部代码,这个也是逻辑的核心内容,下面会分享一下思路(建议对着源码看下):

上面的代码可以整体分为两个步骤,一个创建容器,另一个是从容器中获取bean。

首先说说创建容器的过程

创建容器 -> 扫描.class文件 -> 适配文件路径 -> 判断@Component注解 -> 符合注解进行反射获取对象 -> 记录bean的信息(类型,单例)-> 创建对象 -> 实例化对象 -> 依赖注入 -> aware增强类处理 -> 处理BeanPostProcessor的 postProcessorBeforeInitialazition方法 -> 初始化 -> BeanProcessor的beanPostProcessorAfterInitailzaiton方法 ->处理切面逻辑->bean创建成功

获取bean过程

主要区分单例还是多例,单例从单例池中取,多例新创建一个bean

SmdApplicationContext

package org.smd.spring;

import java.beans.Introspector;
import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.smd.spring.annotation.Autowrite;
import org.smd.spring.annotation.Component;
import org.smd.spring.annotation.ScanComponent;
import org.smd.spring.annotation.Scope;
import org.smd.spring.aware.BeanNameAware;
import org.smd.spring.init.InitializingBean;

/**
 * @author smd
 * @zhName 容器
 * @description: 容器
 */
public class SmdApplicationContext {

  public Map<String, BeanDefinition> definitionMap = new HashMap();
  public Map<String, Object> singletonBeanMap = new HashMap();
  public List<BeanPostProcessor> beanPostProcessors=new ArrayList<BeanPostProcessor>();
  private Class configClass;

  public SmdApplicationContext(Class configClass) {
    this.configClass = configClass;

    //扫描文件夹下数据
    if (configClass.isAnnotationPresent(ScanComponent.class)) {
      ScanComponent scanComponent = (ScanComponent) configClass.getAnnotation(ScanComponent.class);

      //进行文件路径转化
      String path = scanComponent.vaule();
      System.out.println("-->scanComponent:" + path);
      path = path.replace(".", "/");
      System.out.println("-->scanComponent:" + path);

      //加载jar下.class文件
      ClassLoader classLoader = SmdApplicationContext.class.getClassLoader();
      URL resource = classLoader.getResource(path);
      File file = new File(resource.getFile());
      if (file.isDirectory()) {
        for (File f : file.listFiles()) {
          String filePath = f.getAbsolutePath();
          System.out.println("--> file path:" + filePath);
          if (filePath.endsWith(".class")) {

            String filesName = filePath
                .substring(filePath.indexOf("org"), filePath.indexOf(".class"));
            filesName = filesName.replace("\\", ".");
            System.out.println("-->file name" + filesName);
            try {
              Class<?> clazz = classLoader.loadClass(filesName);
              if (clazz.isAnnotationPresent(Component.class)) {

                if(BeanPostProcessor.class.isAssignableFrom(clazz)){
                  BeanPostProcessor beanPostProcessor=(BeanPostProcessor) clazz.newInstance();
                  beanPostProcessors.add(beanPostProcessor);
                }

                Component component = clazz.getAnnotation(Component.class);
                //获取bean name
                String name = component.vaule();
                if (name.equals("")) {
                  name = Introspector.decapitalize(clazz.getSimpleName());
                }
                //记录bean definition
                BeanDefinition definition = new BeanDefinition();
                definition.setType(clazz);
                if (clazz.isAnnotationPresent(Scope.class)) {
                  Scope scope = (Scope) clazz.getAnnotation(Scope.class);
                  definition.setScope(scope.value());
                } else {
                  definition.setScope("singleton");
                }
                //放入bean definition map中
                definitionMap.put(name, definition);
              }
            } catch (ClassNotFoundException e) {
              e.printStackTrace();
            } catch (IllegalAccessException e) {
              e.printStackTrace();
            } catch (InstantiationException e) {
              e.printStackTrace();
            }
          }
        }
      }
    }

    //初始化bean
    for (String name : definitionMap.keySet()) {
      BeanDefinition definition = definitionMap.get(name);
      Object bean = this.createBean(name, definition);
      singletonBeanMap.put(name, bean);
    }
  }

  private Object createBean(String name, BeanDefinition definition) {
    Class clazz = definition.getType();
    try {
      //实例化
      Object bean = clazz.getConstructor().newInstance();

      //依赖注入
      for (Field field : clazz.getDeclaredFields()) {
        if (field.isAnnotationPresent(Autowrite.class)) {
          field.setAccessible(true);
          field.set(bean, getBean(field.getName()));
        }
      }

      // aware加强类回调
      if(bean instanceof BeanNameAware){
        ((BeanNameAware)bean).setBeanName(name);
      }
      // 初始化前调用bean post processor
      for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
        bean= beanPostProcessor.postProcessorBeforeInitialization(name,bean);
      }

      // 初始化
      if(bean instanceof InitializingBean){
        ((InitializingBean)bean).afterPropertiesSet();
      }

      // 初始化后调用bean post processor
      for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
        bean= beanPostProcessor.postProcessorAftertInitialization(name,bean);
      }

      return bean;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  public Object getBean(String name) {

    //获取definition信息
    BeanDefinition definition = definitionMap.get(name);
    if (definition == null) {
      System.out.println("-->error:" + name);
      throw new NullPointerException();
    } else {
      //进行单例和多例区分
      if (definition.getScope().equals("singleton")) {
        Object bean = singletonBeanMap.get(name);
        if (bean == null) {
          return this.createBean(name, definition);
        } else {
          return bean;
        }
      } else {
        return this.createBean(name, definition);
      }
    }
  }
}


各位道友前路漫漫~ 努力向远方前进吧!!!

《真常之道,悟者自得,得悟道者,常清静矣。》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值