《手写Spring渐进式源码实践》-第一章 实现一个简单的SpringBean容器
Java开发这么多年,一直对Spring、SpringBoot底层原理不太熟,所以打算深入学习一下Spring相关的底层原理。
1、SpringBean包含并管理应用对象的配置和生命周期。Spring并不是直接创建一个完整的Java对象并立刻使用,而是先将对象的结构信息(如类名、构造器、依赖属性、作用域等)提取出来作为“定义”,就像把一个完整机器的零部件先记录下来。而这种“拆解”对应的就是BeanDefinition,Spring在解析配置(如XML、注解、JavaConfig)后,会生成BeanDefinition对象,
2、把这个对象的结构信息封装起来统一存入Bean工厂容器中(如DefaultListableBeanFactory),而不是立即实例化。
3、这样做的目的是:
1). 控制对象什么时候创建(懒加载、单例/原型等)。
2). 控制对象生命周期(初始化、销毁)。
3). 自动注入依赖(DI/IOC)。
4). AOP切面织入。
5). 条件装配、环境感知(@Conditional)。
4、相当于把对象解耦:不再通过new去手动创建依赖对象、不需要对象是哪种实现、只需要关心逻辑,不关心对象创建和依赖关系,降低了模块之间的耦合度。
以下是代码:
BeanDefinition是定义Bean对象,用于存储类的结构信息。
public class BeanDefinition {
private Object bean;
public BeanDefinition (Object bean){
this.bean = bean;
}
public Object getBean(){
return this.bean;
}
}
BeanFactory将Bean对象的定义存储到Map中以便获取Bean对象。
public class BeanFactory {
private Map<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
public Object getBean(String name){
return beanDefinitionMap.get(name).getBean();
}
/**
* 注册beanDefinition
* @param name bean名称
* @param beanDefinition beanDefinition对象
*/
public void registerBeanDefinition(String name,BeanDefinition beanDefinition){
beanDefinitionMap.put(name,beanDefinition);
}
}
单元测试类信息:
@SpringBootTest(classes = MyApplication.class)
public class ApiTest {
@Test
public void test_BeanFactory(){
//1、初始化 BeanFactory对象
BeanFactory beanFactory = new BeanFactory();
//2、注册 Bean 对象
beanFactory.registerBeanDefinition("userService",new BeanDefinition(new UserService()));
//3、获取Bean对象
UserService userService = (UserService)beanFactory.getBean("userService");
userService.queryUserInfo();
}
}
github源码地址:https://github.com/Charlie-pang-sys/WeaponSystem/tree/master/Java/Spring-Tutorials/spring-step-01