手写 Spring
Java 中处处是对象,而 Spring 可认为是承载对象的容器,以及对象的管理者
管理的前提必定是需要充分了解这个对象,因此,对象的信息必不可少
对象信息集中式管理的好处:
万丈高楼平地起,如何设计一个 Spring 容器?
定义、注册、获取 |
现在我们有这样一个类
public class Demo {
public void foo() {
System.out.println("执行了Demo下的foo方法");
}
}
Spring如何对其进行管理呢?
public class BeanDefinition {
private Class classInfo;
public BeanDefinition(Class classInfo) {
this.classInfo = classInfo;
}
public Class getClassInfo() {
return classInfo;
}
}
数据结构多用于处理同类数据,合理的组织结构,可以更加充分的利用数据,以及更快的获取所需信息
根据名称,获取对应对象信息,Map 再适合不过了
public class BeanFactory {
private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
public Object getBean(String name) throws InstantiationException, IllegalAccessException {
Class classInfo = beanDefinitionMap.get(name).getClassInfo();
return classInfo.newInstance();
}
public void registerBeanDefinition(String name, BeanDefinition beanDefinition) {
beanDefinitionMap.put(name, beanDefinition);
}
}
public class Main {
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
// 1.初始化 BeanFactory
BeanFactory beanFactory = new BeanFactory();
// 1. 定义
BeanDefinition beanDefinition = new BeanDefinition(Demo.class);
// 2. 注册
beanFactory.registerBeanDefinition("demo", beanDefinition);
//3. 获取
Demo demo = (Demo) beanFactory.getBean("demo");
demo.foo();
}
}
将类的信息定义在 XML 文件中,方便统一管理
使得我们可以
<beans>
<bean id="demo" class="cn.foo.Demo"/>
beans>
// 1.初始化 BeanFactory
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
// 2. 获取Bean对象调用方法
Demo demo = applicationContext.getBean("demo", Demo.class);
demo.foo();
1 创建BeanFacotry,并加载BeanDefinition
2 获取BeanFactory
3 添加 ApplicationContextAwareProcessor
4 调用BeanFactoryPostProcessor
5 添加 BeanPostProcessor
6 初始化事件调用者
7 注册所有事件,同时对事件进行实例化
8 提前实例化单例 Bean
9 调用容器刷新事件
它俩都是PostProcessor(后置处理器) ,别人忙完了才轮到它
BeanFactory 是与BeanDefinition
相关的
Bean是和实例化之后的对象
相关的
它俩在应用上下文的refresh()方法下,实例化自身之后(因为getBeanOfType内调用了getBean方法),一个是立即调用,一个是添加,等到createBean的时候再调用
实例化所有继承了BeanFactory后置处理器接口的Bean,
并调用postProcessBeanFactory(BeanFactory的后置处理方法),(实例化之后就立即调用)
提供修改 BeanDefinition 属性的机会
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
实例化所有继承了Bean后置处理器接口的Bean,
并添加到AbstractBeanFactory(抽象Bean工厂)的beanPostProcessors中
用于在getBean方法下的初始化方法前后的扩展
beanFactory.getBeansOfType(BeanPostProcessor.class);
beanFactory.addBeanPostProcessor(beanPostProcessor);
FactoryBean:工厂Bean,用于创建Bean的Bean
可以这么认为,凡是实现了FactoryBean接口的Bean,一定有两个Bean,
一个是工厂Bean本身,另一个是工厂Bean创建出来的Bean
工厂Bean在getBean方法的时候,
会调用并返回(如果factoryBeanObjectCache不存在的话)
FactoryBean接口下的getObject方法、该方法的返回值
代理的本质就是通过后置处理器,将拦截到的Bean进行一层代理,之后再返回对应代理对象