讲解
首先来看看时序图,然后我们来讲解一下具体过程。

第一点,可以靠这个时序图大致摸清程序运行过程,接着我们直接DEBUG。
先看下图,这里就是主体方法实现,而我们直接运行,你会发现第一次调用,bean依然为空,当第二次调用你会发现bean就有值了。
第二点,认识模板模式。一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
可以查看这篇记录,模板方法模式。
第三点,依靠模板模式设计Spring容器,使用两个Map对象来存放相同的对象。其中,一个Map使用单例模式,构建一个新的实例对象;一个Map使用模板模式,构建多个实例对象,存放Bean管理,这就是Spring Bean的原理。
实例
创建BeanFactory接口
/*** BeanFactory是一个顶层接口,是最基本的Bean容器。* Spring使用BeanFactory来生成,配置和管理Bean。*/public interface BeanFactory {Object getBean(String name) throws BeansException;}
创建Spring bean的建模对象
/*** Spring bean的建模对象* BeanDefinition 用于保存 Bean 的相关信息,包括属性、构造方法参数、依赖的 Bean 名称及是否单例、延迟加载等,* 它是实例化 Bean 的原材料,Spring 就是根据 BeanDefinition 中的信息实例化 Bean。*/public class BeanDefinition {/*** class基本信息:类型、包名*/private Class beanClass;public BeanDefinition(Class beanClass) {this.beanClass = beanClass;}public Class getBeanClass() {return beanClass;}public void setBeanClass(Class beanClass) {this.beanClass = beanClass;}}
创建一个bean定义注册的接口
public interface BeanDefinitionRegistry {/*** 向注册表中注册 BeanDefinition** @param beanName* @param beanDefinition*/void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);}
public interface SingletonBeanRegistry {Object getSingleton(String beanName);}
public class BeansException extends RuntimeException {public BeansException(String msg) {super(msg);}public BeansException(String msg, Throwable cause) {super(msg, cause);}}
创建默认多对象工厂
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {/*** Spring管理容器,注入的Bean是否放入Spring中*/private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();/*** 注册BeanDefinition中* @param beanName 注入bean的名字* @param beanDefinition 注入bean的定义*/@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {beanDefinitionMap.put(beanName, beanDefinition);}/*** 获取bean的定义* @param beanName 注入bean的名字* @return 注入Bean的定义* @throws BeansException 没有注入Bean的异常*/@Overridepublic BeanDefinition getBeanDefinition(String beanName) throws BeansException {BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if (beanDefinition == null) throw new BeansException("No bean named '" + beanName + "' is defined");return beanDefinition;}}
创建抽象BeanFactory实现
/*** 模板模式* 一个抽象类公开定义了执行它的方法的方式/模板。* 它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。** BeanDefinition 注册表接口*/public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {/*** 在模板模式中这是主体方法,整体的自身方法都在这里调用* 获取单例Bean* @param name* @return* @throws BeansException*/@Overridepublic Object getBean(String name) throws BeansException {// 获取初始化的BeanObject bean = getSingleton(name);// Spring容器中的Bean存在,为单例Bean注入后,获取到的bean不为空的场合if (bean != null) {// 返回beanreturn bean;}// 获取bean的定义BeanDefinition beanDefinition = getBeanDefinition(name);// 返回一个实例化对象return createBean(name, beanDefinition);}/*** 在模板模式中这是按需方法,主体方法选择调用子方法* 获取bean的定义* @param beanName 注入bean的名字* @return 注入Bean的定义* @throws BeansException 没有注入Bean的异常*/protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;/*** 在模板模式中这是按需方法,主体方法选择调用子方法* 创建实例化对象* @param beanName bean名字* @param beanDefinition bean定义* @return Spring容器中的实例化对象* @throws BeansException 该Bean不存在*/protected abstract Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException;}
创建默认单例Bean注册
/*** 在模板模式中,这里是模板方法,将用于构造整个单例事件* 默认单例Bean注册*/public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {/*** 单例容器,存放初始化后的Bean* 第一次bean注册后,不再需要将Bean重复存放到Spring容器中* 第一次创建实例对象,验证注册成功后的Bean,使用Spring容器中的Bean调用方法* 第二次创建实例对象,直接使用单例模式下的对象调用方法*/private Map<String, Object> singletonObjects = new HashMap<>();/*** 获取单例Bean** @param beanName* @return*/@Overridepublic Object getSingleton(String beanName) {return singletonObjects.get(beanName);}/*** 注入单例Bean* @param beanName* @param singletonObject*/protected void addSingleton(String beanName, Object singletonObject) {singletonObjects.put(beanName, singletonObject);}}
创建抽象自动装配BeanFactory中
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {/*** 创建实例化对象* @param beanName bean名字* @param beanDefinition bean定义* @return Spring容器中的实例化对象* @throws BeansException 该Bean不存在*/@Overrideprotected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException {Object bean = null;try {// 通过反射获取对象bean = beanDefinition.getBeanClass().newInstance();} catch (InstantiationException | IllegalAccessException e) {throw new BeansException("Instantiation of bean failed", e);}// 同时,将bean注入到单例容器中,防止重复创建实例对象,浪费资源addSingleton(beanName, bean);return bean;}}
最后测试类
public class ApiTest {@Testpublic void test_BeanFactory(){// 1.初始化 BeanFactoryDefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();// 2.注册 beanBeanDefinition beanDefinition = new BeanDefinition(UserService.class);beanFactory.registerBeanDefinition("userService", beanDefinition);// 3.第一次获取 beanUserService userService = (UserService) beanFactory.getBean("userService");userService.queryUserInfo();// 4.第二次获取 bean from SingletonUserService userService_singleton = (UserService) beanFactory.getBean("userService");userService_singleton.queryUserInfo();}}
public class UserService {public void queryUserInfo(){System.out.println("查询用户信息");}}
