手写一个Springioc容器伪代码,Spring中ioc容器的源码解读,Spring中ioc容器的流程梳理。

IOC容器源码

重要方法 refresh (刷新工程)

public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // 准备刷新 准备蛋糕店,基本上就是设置日志,并且new了一个LinkedHashSet
      //this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
      prepareRefresh();

      // 创建一个beanFeactory loadBeanDefinitions(beanFactory)获取蛋糕的制作流程
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);
       //忽略对应的自动装配
       //beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

      try {
          //spring的扩展 空方法
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

          //bean工厂已经基本好了 调用Beanfactory的后置处理器(beanFactory)
         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         initMessageSource();

         // Initialize event multicaster for this context.
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         onRefresh();

         // Check for listener beans and register them.
         registerListeners();

          //初始化方法,就是对bean的依赖进行填充
         // Instantiate all remaining (non-lazy-init) singletons.
         finishBeanFactoryInitialization(beanFactory);

          //spring的扩张方法
         // Last step: publish corresponding event.
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}
复制代码

实现BeanFactroyPostProcessors接口,这个方法是BeanFactory创建完成后执行的,这是Spring的扩展,用户能添加功能

public class MyBeanFactoryPostProcessors implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    }
}
复制代码

在finishBeanFactoryInitialization(beanFactory);初始化bean之后会执行initializeBean的方法

// 已经完成了创建和属性填充给你的工作
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
		// 1、调用实现的aware接口
           invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            // 调用beanpostproccessor的BeforeInitialization方法
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
            // 调用初始化方法在这里 使用xml指定的初始化方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
            // 调用beanpostproccessor的AfterInitialization
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
复制代码

实现BeanPostProcessors接口 能实现两个方法postProcessBeforeInitialization,postProcessAfterInitialization 分别是初始化之前调用,初始化之后调用,写整个类也是Spring提供的扩展

public class MyBeanPostProcessors implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}
复制代码

手写一个ioc容器

package top.lzy.spring.api.impl;

import top.lzy.clinet.D;
import top.lzy.spring.api.*;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 卢占勇
 * @desc
 * @date 2022/3/17
 */
public class ClassPathXmlApplicationContext implements ApplicationContext {

    private ConcurrentHashMap<String,Object> beanFactory;
    private ConcurrentHashMap<String, BeanFactroyPostProcessor> beanFactroyPostProcessor = new ConcurrentHashMap<>(64);
    private ConcurrentHashMap<String,BeanPostProcessor> beanPostProcessor = new ConcurrentHashMap<>(64);
    private Properties beanDefinitions = new Properties();

    public ClassPathXmlApplicationContext(String config) {
        InputStream inputStream = readXML(config);
        try {
            //将propertise文件直接加载为类
            beanDefinitions.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        refresh();
    }

    private void refresh() {

        //1、准备环境
        prepareRefresh();

        //2、创建店面
        beanFactory = new ConcurrentHashMap(64);

        //3、准备Beanfactory 忽略一些东西
        prepareBeanFactory(beanFactory);

        try {
            //4 、 客户可以重写该方法 后置处理容器,例如:再添加一个bean
            postProcessBeanFactory(beanFactory);
            // 调用beanFactory后置处理器
            invokeBeanFactoryPostProcessors(beanFactory);
            //注册BeanPostProcessors
            registerBeanPostProcessors(beanFactory);
            //完成实例化bean,并注入依赖
            finishBeanFactoryInitialization(beanFactory);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    private void registerBeanPostProcessors(ConcurrentHashMap<String, Object> beanFactory) {
        //拿到所以的bean的后置处理器,然后注册
        beanPostProcessor.put("D",new D());
    }

    private void invokeBeanFactoryPostProcessors(ConcurrentHashMap<String, Object> beanFactory) {
        //找到beanFactory的后置处理器 然后调用它的方法
        //一般用来修改bean的定义 现在beanFactory还没有bean 因为没有初始化
        for (Map.Entry<String,BeanFactroyPostProcessor> entry:beanFactroyPostProcessor.entrySet()){
            BeanFactroyPostProcessor bfpp = entry.getValue();
            bfpp.postProcessBeanFactory(beanFactory);
        }
    }

    private void finishBeanFactoryInitialization(ConcurrentHashMap<String, Object> beanFactory) {

        //1、创建
        for (Map.Entry<Object,Object> entry:beanDefinitions.entrySet()) {
            String className = (String) entry.getValue();

            Constructor beanContructor = null;
            Object bean =null;
            try {
                beanContructor = Class.forName(className).getConstructor();
                bean = beanContructor.newInstance();
                beanFactory.put((String) entry.getKey(), bean);
            } catch (NoSuchMethodException | ClassNotFoundException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
            //2、依赖注入

            //4、初始化前 beforeBeanPostProcessor
            for (Map.Entry<String,BeanPostProcessor> entry1:beanPostProcessor.entrySet()){
                entry1.getValue().postProcessBeforeInitialization(bean,(String) entry.getKey());
            }

            //调用aware
            if (bean instanceof ApplicationContextAware){
                ApplicationContextAware applicationContextAware = (ApplicationContextAware) bean;
                applicationContextAware.setApplicationContextAware(this);
            }

            //5、初始化
            if (bean instanceof Init){
                Init init = (Init) bean;
                init.init();
            }

            //6、初始化化后 afterBeanPostProcessor
            for (Map.Entry<String,BeanPostProcessor> entry1:beanPostProcessor.entrySet()){
                entry1.getValue().postProcessAfterInitialization(bean,(String) entry.getKey());
            }

            beanFactory.put((String) entry.getKey(),entry.getValue());
        }


    }

    private void postProcessBeanFactory(ConcurrentHashMap<String, Object> beanFactory) {
        System.out.println("正在解析注解");
        beanFactroyPostProcessor.put("bf",new ConfigBeanFactoryPostProcessor());
    }

    private void prepareBeanFactory(ConcurrentHashMap<String, Object> beanFactory) {

    }

    private void prepareRefresh() {
        System.out.println("准备刷新,基本上就是设置日志,并且new了一个LinkedHashSet, 看适不适合蛋糕店");
    }

    @Override
    public Object getBean(String name) {
        return beanFactory.get(name);
    }

    @Override
    public InputStream readXML(String config) {
        return Thread.currentThread().getContextClassLoader().getResourceAsStream(config);
    }
}

复制代码

手写一个ioc容器梳理过程

梳理ClassPathXmlApplicationComtext一下流程

1、在构造器中去读取配置文件,将配置文件加载为一个类,然后进入核心方法刷新

2、先准备刷新工作,该过程就是设置一下日志,(就是看看合不合适创建蛋糕店)

3、创建一个店面,基本理解为一个容器吧(整个过程其实很复杂,手写的简化了)

4、准备beanFactory,就是忽略一些东西,例如忽略对应的自动装配

5、进入try(我认为这个时候进入try就是因为下面就有客户能扩展的一些方法)

6、后置处理beanFactory(postProcessBeanFactory),这是一个空方法,客户端能够重写该方法,能够添加一些bean,解析注解等

7、调用beanfactory后置处理器,找到beanFactory后置处理器,然后调用它的方法postProcessBeanFactory

8、注册bean后置处理器,拿到所以bean的后置处理器然后注册到该类的成员属性map中

9、开始进入初始化bean的方法

​ 1、创建,通过全限定名拿到class对象,拿到构造器,实例化

​ 2、通过类对象拿到成员变量注入依赖

​ 3、使用bean的后置处理器,调用初始化前的处理器方法

​ 4、查看该对象是否实现ApplicationAware,实现set方法

​ 5、调用初始化方法,就那个xml注册的初始化方法init-method

​ 6、使用bean的后置处理器,调用初始化后的处理器方法

猜你喜欢

转载自juejin.im/post/7076083316595621896