前文我们介绍了关于如何学习Spring的源码以及解析了spring中加载配置文件注册Beandefinition的过程。今天我们继续学习DI的过程。
创建实例和DI过程IOC和DI都是对spring容器特性的描述。IOC指的是将实例的生命周期交给第三方管理(spring)。而DI的侧重点在于某一个类依赖了其他的实例,将实例注入到依赖它的实例的过程。所以可以很明显的看出来DI是发生在类实例已经实例化完成之后的。
创建实例 BeanDefinitionBeanDefinition是对bean属性的定义,包含了bean的状态的属性,如bean的Class对象,单例还是原型等。
上图中是BeanDefinition定义的方法,可以看出其中包括创建Bean的工厂类名称和bean的状态单例,懒加载等。
其中大多数方法都很容易理解,有几个属性这里需要解释下。
dependsOndependsOn是指当前Beandefinition所表示的Bean依赖了其他那些bean(不包括基本数据类型),这里依赖的bean并不需要在当前Bean中声明,所以不能通过依赖注入完成,而是需要显示的定义。
autowireCandidateautowireCandidate用来表示当前bean是否可以被注入到其他实例中。
上面的内容都可以通过xml配置或者注解来配置。
xml
<bean scope="singleton" autowire-candidate="true" init-method="" factory-method="" lazy-init="true" > </bean>注解
public class JavaBean { public void init(){ //init } public void destroy(){ //destroy } @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) @Bean(initMethod = "init", destroyMethod = "destroy") public JavaBean getEntity(){ return new JavaBean(); } } 继承体系在上图中实际实际被用来实现Beandefinition的类是RootBeanDefinition,ChildBeanDefinition,GenericBeanDefinition。其中GenericBeanDefinition是在spring2.5以后才出现的,spring2.5以后都建议使用GenericBeanDefinition。但是由于以前的代码都是使用RootBeanDefinition和ChildBeanDefinition,所以我们也还能看到RootBeanDefinition,ChildBeanDefinition这些类。
大体流程同IOC一样在阅读源码前先来看看一DI的大体流程。
refresh()在阅读IOC相关实现的时候,除开构造函数外refresh()就是我们最初的入口,当时只是看了其中的部分代码。实际上refresh()贯穿了spring启动的整个阶段。当refresh()方法执行完成时基本就代表spring正常启动了。在DI篇我们来继续看refresh()的其他的一些代码。
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //读取配置文件 注册Beandefinition prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); registerBeanPostProcessors(beanFactory); initMessageSource(); initApplicationEventMulticaster(); onRefresh(); registerListeners(); finishBeanFactoryInitialization(beanFactory); finishRefresh(); }catch (BeansException ex) { logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex); destroyBeans(); cancelRefresh(ex); throw ex; } } } BeanFactoryPostProcessor和BeanPostProcessor在进行bean的实例化之前会先执行BeanFactoryPostProcessor和注册BeanPostProcessor。
BeanFactoryPostProcessorpublic interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;}
```
实现BeanPostProcessor接口可以在Bean初始化的前后做一些自定义的操作,但是不能够直接操作BeanDefinition元数据。
BeanFactoryPostProcessor和BeanPostProcessor都是spring留给我们进行扩展的类。通过实现这两个接口我们可以在bean的实例化过程中添加一些自定义的操作。而需要注意的是这两个接口虽然都提供了扩展bean实例化的功能,但两者确实完全不同的:
BeanFactoryPostProcessor是在所有的bean都未开始实例化前调用,其可以拿到容器中所有的Beandefinition,所以可以在bean实例化前直接修改bean定义的元数据。