技术JavaSpring面向对象手写 Spring IoC - Bean 的实例化与依赖注入
penjc前文:
面向过程手写 Spring IoC
手写 Spring IoC 模块设计
手写 Spring IoC 容器 —— BeanDefinition 加载与解析
手写 Spring IoC 容器 —— Bean 的实例化与依赖注入
引言
在 Spring IoC 容器的核心功能中,Bean 的实例化与依赖注入至关重要。
本文将实现 Spring IoC 的实例创建部分:
- 定位并加载XML资源文件
- 创建Document文档对象
- 解析Document文档
- 解析Document中的Bean标签
- 注册BeanDefinition
1. BeanFactory 设计
BeanFactory
是 Spring IoC 容器的顶级接口,定义了 getBean
方法。
1 2 3 4 5 6 7 8 9
| / * Spring 容器的顶级接口 */ public interface BeanFactory { / * 根据 bean 名称获取实例 */ Object getBean(String beanName); }
|
设计思路:
- 统一所有 IoC 容器的基本行为。
- 允许不同的
BeanFactory
实现,例如 ListableBeanFactory
、AutowireCapableBeanFactory
。
2. 抽象工厂 AbstractBeanFactory
AbstractBeanFactory
继承 DefaultSingletonBeanRegistry
,负责 Bean 的获取逻辑。
抽象了getBean 方法逻辑
- 先从单例Bean的map集合中查找,如果找到直接返回
- 不存在,则从Bean的定义信息集合中查找对应的BeanDefinition
- 判断该Bean是单例还是多例
- 如果是单例,创建Bean实例并存入单例Bean的map集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory { @Override public Object getBean(String beanName) { Object singletonObject = getSingleton(beanName); if (singletonObject != null){ return singletonObject; }
BeanDefinition bd = getBeanDefinition(beanName); if (bd == null){ return null; }
if (bd.isSingleton()) { singletonObject = createBean(bd); addSingleton(beanName, singletonObject); } else if (bd.isPrototype()) { singletonObject = createBean(bd); }
return singletonObject; }
protected abstract BeanDefinition getBeanDefinition(String beanName); protected abstract Object createBean(BeanDefinition bd); }
|
设计思路:
- 模板方法模式:
getBean
是 模板方法,抽象了 Bean 的获取流程,具体实现由子类完成。
getBeanDefinition
由子类实现,不同 BeanFactory
可以有不同的 BeanDefinition
解析方式。
createBean
由子类实现,不同 BeanFactory
可以有不同的 Bean
创建方式。
- 单例管理:
- 先检查
singletonObjects
缓存,避免重复创建 Bean。
- 如果是 单例,则创建后存入
singletonObjects
。
- 如果是 多例,则每次调用
getBean
都创建新的实例。
3. Bean 的创建与依赖注入
AbstractAutowireCapableBeanFactory
负责 实例化 Bean、依赖注入、初始化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory { @Override protected Object createBean(BeanDefinition bd) { Object bean = null; try { bean = createBeanInstance(bd); populateBean(bean, bd); initializeBean(bean, bd); } catch (Exception e) { e.printStackTrace(); } return bean; }
|
设计思路:
createBeanInstance
:通过 反射 创建 Bean 实例。
populateBean
:解析 property
属性并注入。
initializeBean
:执行 init-method
方法。
3.1 Bean 实例化
1 2 3
| private Object createBeanInstance(BeanDefinition bd) throws Exception { return ReflectUtils.createBean(bd.getClazzType()); }
|
为什么不直接 new
?
Bean
可能需要 通过工厂方法创建。
Bean
可能 代理对象(如 AOP 代理)。
- 解耦实例化方式,可以扩展 多种创建策略。
3.2 依赖注入
1 2 3 4 5 6 7 8 9 10 11 12
| private void populateBean(Object bean, BeanDefinition bd) throws Exception { List<PropertyValue> propertyValues = bd.getPropertyValues(); for (PropertyValue pv : propertyValues) { String name = pv.getName(); Object value = pv.getValue(); BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this); Object valueToUse = valueResolver.resolveValue(value); ReflectUtils.setProperty(bean, name, valueToUse); } }
|
设计思路:
- 解析
property
的 value
或 ref
。
- 通过
ReflectUtils
反射注入属性。
3.3 初始化 Bean
1 2 3 4 5 6 7 8 9
| private void initializeBean(Object bean, BeanDefinition bd) throws Exception { if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(this); } if (bean instanceof InitializingBean) { ((InitializingBean) bean).afterPropertiesSet(); } invokeInitMethod(bean, bd); }
|
设计思路:
- 处理
Aware
接口,如 BeanFactoryAware
。
- 执行
InitializingBean
的 afterPropertiesSet
方法。
- 调用
init-method
指定的初始化方法。
1 2 3 4 5 6
| private void invokeInitMethod(Object bean, BeanDefinition bd) throws Exception { String initMethod = bd.getInitMethod(); if (initMethod != null) { ReflectUtils.invokeMethod(bean, initMethod); } }
|
4. 单例管理
Spring 通过 SingletonBeanRegistry
维护单例 Bean。
1 2 3 4
| public interface SingletonBeanRegistry { Object getSingleton(String beanName); void addSingleton(String beanName, Object bean); }
|
DefaultSingletonBeanRegistry
实现了 SingletonBeanRegistry
。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry { private Map<String, Object> singletonObjects = new HashMap<>();
@Override public Object getSingleton(String beanName) { return this.singletonObjects.get(beanName); }
@Override public void addSingleton(String beanName, Object bean) { this.singletonObjects.put(beanName, bean); } }
|
设计思路:
- 维护
singletonObjects
单例缓存池。
- 通过 线程安全的方式 存储单例 Bean(可扩展双重检查锁)。
5. BeanDefinition 注册
Spring 基本容器。
底层操作 BeanDefinition Map 的核心实现类,实现了 BeanDefinitionRegistry 接口,负责注册或获取 BeanDefinition。
同时继承了 AbstractAutowireCapableBeanFactory 抽象工厂。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry , ListableBeanFactory { private Map<String,BeanDefinition> beanDefinitions = new HashMap<>();
@Override public BeanDefinition getBeanDefinition(String beanName) { return this.beanDefinitions.get(beanName); }
@Override public List<BeanDefinition> getBeanDefinitions() { List<BeanDefinition> beanDefinitionList = new ArrayList<>(); for (BeanDefinition bd : beanDefinitions.values()){ beanDefinitionList.add(bd); } return beanDefinitionList; }
@Override public void registerBeanDefinition(String beanName, BeanDefinition bd) { this.beanDefinitions.put(beanName,bd); }
@Override public <T> List<T> getBeansByType(Class type) { List<T> results = new ArrayList<>();
List<BeanDefinition> beanDefinitions = getBeanDefinitions(); for (BeanDefinition bd : beanDefinitions) { Class<?> clazzType = bd.getClazzType();
if (type.isAssignableFrom(clazzType)){ results.add((T) getBean(bd.getBeanName())); } } return results; }
@Override public List<String> getBeanNamesByType(Class type) { return null; } }
|