手写Spring基本功能

63 阅读1分钟
  1. 通过手写模拟,了解Spring的底层源码启动过程
  2. 通过手写模拟,了解BeanDefiniton、BeanPostProcessor的概念
  3. 通过手写模拟,交接Spring解析配置类底层源码工作流程
  4. 通过手写模拟,了解依赖注入,Aware回调等底层源码工作流程
  5. 通过手写模拟,了解Spring Aop的底层源码工作流程

部分手写Spring代码

` /**

  • @author ZXZG

  • @date 2023/11/1 21:49 */ public class YttApplication {

    private Class clazz;

    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();

    private Map<String, Object> singletonBeanMap = new HashMap<>();

    private List beanPostProcessors = new ArrayList<>();

    public YttApplication(Class clazz) { this.clazz = clazz;

     // 扫描配置类,获取BeanDefinitionMap
     scan();
    
     for (String beanName : beanDefinitionMap.keySet()) {
         creteBean(beanName);
     }
    
     // 创建单例bean
    

    }

    public Object creteBean(String beanName) {

     return createSingletonBean(beanName, beanDefinitionMap.get(beanName));
    

    }

    private Object createSingletonBean(String beanName, BeanDefinition beanDefinition) {

     if ("singleton".equals(beanDefinition.getScope())) {
         try {
             if (null != singletonBeanMap.get(beanName)) {
                 return singletonBeanMap.get(beanName);
             }
    
             Class clazz = beanDefinition.getType();
             Object instance = clazz.getConstructor().newInstance();
             singletonBeanMap.put(beanName, instance);
    
             for (Field field : clazz.getDeclaredFields()) {
                 if (field.isAnnotationPresent(YttAutowired.class)) {
                     field.setAccessible(true);
                     field.set(instance, null != getBean(field.getName()) ? getBean(field.getName()) : creteBean(field.getName()));
                 }
             }
    
             for (YttBeanPostProcessor beanPostProcessor : beanPostProcessors) {
                 beanPostProcessor.postProcessBeforeInitialization(instance, beanName);
             }
    
             if (instance instanceof YttInitializingBean) {
                 ((YttInitializingBean) instance).afterPropertiesSet();
             }
    
             for (YttBeanPostProcessor beanPostProcessor : beanPostProcessors) {
                 beanPostProcessor.postProcessAfterInitialization(instance, beanName);
             }
    
             return instance;
         } catch (InvocationTargetException e) {
             throw new RuntimeException(e);
         } catch (InstantiationException e) {
             throw new RuntimeException(e);
         } catch (IllegalAccessException e) {
             throw new RuntimeException(e);
         } catch (NoSuchMethodException e) {
             throw new RuntimeException(e);
         }
     }
     return null;
    

    }

    public void scan() {

     for (Annotation annotation : clazz.getAnnotations()) {
         if (annotation instanceof YttComponentScan) {
             YttComponentScan scan = (YttComponentScan) annotation;
             String path = scan.value();
             path = path.replaceAll("\\.", "/");
             String resource = YttApplication.class.getClassLoader().getResource(path).getFile();
             File file = new File(resource);
             for (File listFile : file.listFiles()) {
                 String absolutePath = listFile.getAbsolutePath();
                 absolutePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class")).replaceAll("\\\\", ".");
                 try {
                     Class<?> aClass = Class.forName(absolutePath);
                     if (aClass.isAnnotationPresent(YttComponent.class)) {
                         BeanDefinition beanDefinition = new BeanDefinition();
                         beanDefinition.setType(aClass);
                         if (aClass.isAnnotationPresent(YttScope.class)) {
                             YttScope yttScope = aClass.getAnnotation(YttScope.class);
                             beanDefinition.setScope(yttScope.value());
                         }
                         String beanName = aClass.getAnnotation(YttComponent.class).value();
                         beanDefinitionMap.put(beanName, beanDefinition);
    
                         if (YttBeanPostProcessor.class.isAssignableFrom(aClass)) {
                             YttBeanPostProcessor instance = (YttBeanPostProcessor) aClass.getConstructor().newInstance();
                             beanPostProcessors.add(instance);
                         }
                     }
                 } catch (ClassNotFoundException e) {
                     throw new RuntimeException(e);
                 } catch (InvocationTargetException e) {
                     throw new RuntimeException(e);
                 } catch (InstantiationException e) {
                     throw new RuntimeException(e);
                 } catch (IllegalAccessException e) {
                     throw new RuntimeException(e);
                 } catch (NoSuchMethodException e) {
                     throw new RuntimeException(e);
                 }
             }
    
         }
     }
    

    }

    public Object getBean(String beanName) {

     BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
     if ("singleton".equals(beanDefinition.getScope())) {
         return singletonBeanMap.get(beanName);
     } else {
         return creteBean(beanName);
     }
    

    } } `