手写模拟Spring底层原理-Bean的创建与获取
字数 1196 2025-08-11 08:35:47
手写模拟Spring底层原理:Bean的创建与获取
1. 引言
本教学文档将详细讲解如何手动实现Spring框架的核心功能,包括Bean的创建与获取机制。通过这个简易版本的实现,我们可以深入理解Spring的底层原理。
2. 核心组件设计
2.1 主要类结构
- JdApplicationContext: Spring启动类,实现bean的加载和获取功能
- UserService/OrderService: Bean的实现类
- App: 启动测试类
- AppConfig: 启动配置类
2.2 核心注解
@Component: 标识需要创建Bean的类@Autowired: 用于依赖注入@Scope: 定义Bean的作用域(单例/原型)
3. 实现步骤详解
3.1 启动流程
- 初始化入口:
// App类作为入口
public class App {
public static void main(String[] args) {
JdApplicationContext context = new JdApplicationContext(AppConfig.class);
UserService userService = (UserService) context.getBean("userService");
userService.test();
}
}
- JdApplicationContext构造函数:
public JdApplicationContext(Class<?> configClass) {
// 1. 扫描配置类指定的包路径
// 2. 创建并缓存BeanDefinition
// 3. 初始化单例Bean
}
3.2 BeanDefinition的创建与缓存
-
扫描类路径:
- 通过AppConfig配置类获取扫描路径
- 查找带有
@Component注解的类
-
创建BeanDefinition:
public class BeanDefinition {
private Class<?> clazz; // Bean类
private String beanName; // Bean名称
private String scope; // 作用域(singleton/prototype)
// getter/setter方法
}
- 缓存到beanDefinitionMap:
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
3.3 Bean的初始化与依赖注入
- 初始化流程:
private Object createBean(String beanName, BeanDefinition beanDefinition) {
// 1. 通过反射实例化对象
Class<?> clazz = beanDefinition.getClazz();
Object instance = clazz.newInstance();
// 2. 依赖注入(处理@Autowired注解)
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Autowired.class)) {
String fieldBeanName = field.getAnnotation(Autowired.class).value();
if (fieldBeanName.isEmpty()) {
fieldBeanName = field.getName();
}
Object fieldBean = getBean(fieldBeanName);
field.setAccessible(true);
field.set(instance, fieldBean);
}
}
// 3. 初始化回调(处理InitializingBean接口)
if (instance instanceof InitializingBean) {
((InitializingBean) instance).afterPropertiesSet();
}
return instance;
}
- getBean方法实现:
public Object getBean(String beanName) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition == null) {
throw new RuntimeException("No bean named " + beanName);
}
if ("prototype".equals(beanDefinition.getScope())) {
// 原型模式每次都创建新实例
return createBean(beanName, beanDefinition);
} else {
// 单例模式从缓存获取
Object bean = singletonBeanMap.get(beanName);
if (bean == null) {
bean = createBean(beanName, beanDefinition);
singletonBeanMap.put(beanName, bean);
}
return bean;
}
}
3.4 循环依赖解决方案
- 问题描述:
// UserService
@Component
public class UserService {
@Autowired
private OrderService orderService;
}
// OrderService
@Component
public class OrderService {
@Autowired
private UserService userService;
}
- 二级缓存方案:
private final Map<String, Object> singletonBeanMap = new ConcurrentHashMap<>(); // 一级缓存
private final Map<String, Object> creatingBeanMap = new ConcurrentHashMap<>(); // 二级缓存
public Object getBean(String beanName) {
// 检查一级缓存
Object singleton = singletonBeanMap.get(beanName);
if (singleton != null) return singleton;
// 检查二级缓存(正在创建中的Bean)
Object creatingBean = creatingBeanMap.get(beanName);
if (creatingBean != null) return creatingBean;
// 创建新实例
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition == null) throw new RuntimeException("No bean named " + beanName);
// 标记为正在创建
Object bean = createBean(beanName, beanDefinition);
creatingBeanMap.put(beanName, bean);
// 完成创建后移入一级缓存
if ("singleton".equals(beanDefinition.getScope())) {
singletonBeanMap.put(beanName, bean);
creatingBeanMap.remove(beanName);
}
return bean;
}
3.5 扩展点实现
- InitializingBean接口:
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
- BeanPostProcessor接口(模拟AOP):
public interface BeanPostProcessor {
default Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
default Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
- AOP实现示例:
@Component
public class AopBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof UserService) {
// 创建代理对象
return Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
(proxy, method, args) -> {
System.out.println("AOP before...");
Object result = method.invoke(bean, args);
System.out.println("AOP after...");
return result;
});
}
return bean;
}
}
4. 完整流程总结
-
启动阶段:
- 扫描配置类指定的包路径
- 识别
@Component注解的类并创建BeanDefinition - 缓存BeanDefinition到beanDefinitionMap
- 识别并缓存BeanPostProcessor实现类
-
Bean获取阶段:
- 检查一级缓存(singletonBeanMap)
- 检查二级缓存(creatingBeanMap)
- 创建新实例(反射)
- 依赖注入(处理@Autowired)
- 执行BeanPostProcessor前置处理
- 执行InitializingBean.afterPropertiesSet()
- 执行BeanPostProcessor后置处理
- 缓存单例Bean
-
扩展机制:
- InitializingBean: 属性设置后的回调
- BeanPostProcessor: Bean初始化前后的处理点
5. 进一步扩展方向
- 实现BeanFactory接口体系
- 添加@Lazy延迟加载支持
- 完善AOP切面表达式匹配
- 实现@Configuration配置类支持
- 添加Bean生命周期回调(@PostConstruct/@PreDestroy)
通过这个简易实现,我们深入理解了Spring的核心机制,包括Bean的创建、依赖注入、循环依赖解决和扩展点设计等关键概念。