讲解
首先来看看时序图,然后我们来讲解一下具体过程。
第一点,可以靠这个时序图大致摸清程序运行过程,接着我们直接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的定义
*/
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
beanDefinitionMap.put(beanName, beanDefinition);
}
/**
* 获取bean的定义
* @param beanName 注入bean的名字
* @return 注入Bean的定义
* @throws BeansException 没有注入Bean的异常
*/
@Override
public 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
*/
@Override
public Object getBean(String name) throws BeansException {
// 获取初始化的Bean
Object bean = getSingleton(name);
// Spring容器中的Bean存在,为单例Bean注入后,获取到的bean不为空的场合
if (bean != null) {
// 返回bean
return 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
*/
@Override
public 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不存在
*/
@Override
protected 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 {
@Test
public void test_BeanFactory(){
// 1.初始化 BeanFactory
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 2.注册 bean
BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
beanFactory.registerBeanDefinition("userService", beanDefinition);
// 3.第一次获取 bean
UserService userService = (UserService) beanFactory.getBean("userService");
userService.queryUserInfo();
// 4.第二次获取 bean from Singleton
UserService userService_singleton = (UserService) beanFactory.getBean("userService");
userService_singleton.queryUserInfo();
}
}
public class UserService {
public void queryUserInfo(){
System.out.println("查询用户信息");
}
}