手写Spring

最近在重新学习Spring,记录下自己的学习过程

一、创建工程

创建工程没有什么要求,只会用到java的基础知识,注解接口都是自己定义的,只是简单的实现,了解下spring的原理实现,细节的内容需要深入研究源码,后续会逐步学习

二、项目搭建

目录

一、创建工程

二、项目搭建


​​​​​​​

 spring文件夹中放入spring类,service中就是一些我们业务代码类(暂时就简单的分一下)

1、首先我们需要创建YybApplicationContext作为Spring核心原理的实现类,

   AppConfig作为我们文件的配置类

  UserService

2、需要实现下面代码成功,类的扫描和bean的创建

 1)配置好扫描路径

创建注解ComponentScan

设定扫描路径

2)增加Component注解

3)Spring核心原理伪代码实现

(1)在YybApplicationContext的 有参构造方法中实现扫描,bean创建

package com.spring;

import java.beans.Introspector;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class YybApplicationContest {

  private Class configClass;
  // 扫描所有的bean,创建BeanDefinition
  private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
  // 单例bean
  private Map<String, Object> singletonObject = new HashMap<>();
  // 所有的BeanPostProcessor的实现类
  private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();

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

    // 扫描
    scan(configClass);

    for (Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
      String beanName = entry.getKey();
      BeanDefinition beanDefinition = entry.getValue();
      if (beanDefinition.getScope().equals("singleton")) {
        Object bean = createBean(beanName, beanDefinition);
        singletonObject.put(beanName, bean);
      }
    }
  }

  private Object createBean(String beanName, BeanDefinition beanDefinition) {
    Class clazz = beanDefinition.getType();
    Object instance = null;
    try {
      instance = clazz.getConstructor().newInstance();
      for (Field field : clazz.getDeclaredFields()) {
        if(field.isAnnotationPresent(Autowired.class)){
          field.setAccessible(true);
          field.set(instance,getBean(field.getName()));
        }
      }
      for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
        instance = beanPostProcessor.postProcessBeforeInitialization(instance,beanName);
      }

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

      // BeanPostProcessor
      for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
        instance = beanPostProcessor.postProcessAfterInitialization(instance,beanName);
      }


    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      e.printStackTrace();
    } catch (NoSuchMethodException e) {
      e.printStackTrace();
    }
    return instance;
  }

  private void scan(Class configClass) {
    if (configClass.isAnnotationPresent(ComponentScan.class)) {
      ComponentScan componentScan = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
      String path = componentScan.value();
      path = path.replace(".", "/");
      ClassLoader classLoader = YybApplicationContest.class.getClassLoader();
      URL resource = classLoader.getResource(path);
      File file = new File(resource.getFile());
      if (file.isDirectory()) {
        for (File f : file.listFiles()) {
          BeanDefinition beanDefinition = new BeanDefinition();
          String absolutePath = f.getAbsolutePath();
          absolutePath = absolutePath.substring(absolutePath.indexOf("com"),
              absolutePath.indexOf(".class"));
          absolutePath = absolutePath.replace("\\", ".");
          try {
            Class<?> aClass = classLoader.loadClass(absolutePath);
            beanDefinition.setType(aClass);
            if (aClass.isAnnotationPresent(Component.class)) {
              Component annotation1 = aClass.getAnnotation(Component.class);
              if(BeanPostProcessor.class.isAssignableFrom(aClass)){
                BeanPostProcessor beanPostProcessor = (BeanPostProcessor) aClass.getConstructor().newInstance();
                beanPostProcessorList.add(beanPostProcessor);
              }

              String beanName = annotation1.value();
              if("".equals(beanName)){
                beanName = Introspector.decapitalize(aClass.getSimpleName());
              }
              if (aClass.isAnnotationPresent(Scope.class)) {
                Scope annotation = aClass.getAnnotation(Scope.class);
                String value = annotation.value();
                beanDefinition.setScope(value);
              } else {
                beanDefinition.setScope("singleton");
              }
              beanDefinitionMap.put(beanName, beanDefinition);
            }
          } catch (ClassNotFoundException | NoSuchMethodException e) {
            e.printStackTrace();
          } catch (InvocationTargetException e) {
            e.printStackTrace();
          } catch (InstantiationException e) {
            e.printStackTrace();
          } catch (IllegalAccessException e) {
            e.printStackTrace();
          }

        }
      }


    }
  }

  public Object getBean(String beanName) {
    if (!beanDefinitionMap.containsKey(beanName)) {
      throw new NullPointerException();
    }
    BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
    if (beanDefinition.getScope().equals("singleton")) {
      Object singletonBean = singletonObject.get(beanName);
      if (singletonBean == null){
        singletonBean = createBean(beanName,beanDefinition);
        singletonObject.put(beanName,singletonBean);
      }
      return singletonBean;
    } else {
      // 原型
      Object bean = createBean(beanName, beanDefinition);
      return bean;
    }
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值