IoC是Spring的重要特性之一,IoC是控制反转,即将创建对象的控制权交由容器管理,那么容器是如何创建对象的呢?
接下来我们来学习Bean的生命周期。
首先,第一步,看过Spring源码的童鞋应该都知道在Spring中有一个极其重要的方法——refresh()方法,在这个方法里面做了许多事情,话不多说,让我们先看看这个方法的代码:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
方法里面包含的内容有点多,我们可以选择性的去看就行了,因为光看方法名字大概就知道它干了什么事情了,所以我们只需要把精力花在节骨眼上,obtainFreshBeanFactory()方法从方法名就可以知道获取一个新的BeanFactory实例并且在这个方法里面去解析配置文件获得BeanDefinition的一个集合,这个集合在BeanFactory对象中,用于后期创建Bean,prepareBeanFactory(beanFactory)方法就是准备BeanFactory,从方法字面上意思理解为给BeanFactory实例做准备工作,也可以理解为初始化,postProcessBeanFactory(beanFactory)允许在上下文子类中对bean工厂进行后处理 ,说白了就是给BeanFactory实例添加后置增强处理器,说到这,请童鞋们记住BeanFactoryPostProcessor这个接口,这是个很重要的接口,registerBeanPostProcessors(beanFactory)注册Bean的后置增强处理器,**BeanPostProcessor **也是一个重要的接口,先记住这个接口,initMessageSource()这个就是处理化消息来源,initApplicationEventMulticaster()初始化环境配置,onRefresh()在特定的上下文子类中初始化其他特殊bean ,registerListeners()注册监听器,finishBeanFactoryInitialization(beanFactory)实例化所有不是懒加载的Bean,finishRefresh()发布相应的事件。
在refresh()中的这些方法干的事情都给大家罗列了一下,其中BeanFactoryPostProcessor这个接口只有一个方法,也就是我们所说的函数式接口,他会在得到BeanDefinition集合后执行,主要就是对这个BeanFactory进行补充,比如它的一个实现类PlaceholderConfigurerSupport,这个实现类的作用就是把我们平时在xml中配置的一些占位符替换成对应的内容,比如
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${driver}" />
<property name="url" value="jdbc:${dbname}" />
</bean>
它就可以将${driver}替换成指定的内容。
而PostProcessor接口也是后置增强,不过它增强的对象是Bean,它里面有两个方法,postProcessBeforeInitialization(Object bean, String beanName),postProcessAfterInitialization(Object bean, String beanName)从名字就可以知道这两个方法的执行时机,一个是初始化前执行,一个是初始化后执行,那是不是还少了个初始化?不知道大家还有没有印象,我们在配置对象的时候这个bean标签里面是否还有个init-method属性?这个就是初始化方法。
还有一个重要的接口就是Aware接口,这个接口有很多实现类,那这个接口是做什么用的呢?我们随便拿它的一个子接口来说,BeanNameAware接口中有一个方法setBeanName(String name),这个方法有什么用?见名知意,设置Bean的名字,没错,他就是跟我们set方法没什么区别,我们交由容器创建的类可以实现这个接口,当我们属性填充完成后会回调这个接口中的方法给我们的Bean设置Bean在容器中的名字。
最后,我们先来总结一下Bean的生命周期,时间有限,源码我们下回再说。
创建BeanFacroty对象->解析配置文件获取BeanDefintion集合->添加BeanFactoryPostProcessor对象->执行BeanFactoryPostProcessor的后置增强,对BeanFactory对象进行补充->注册BeanPostProcessor后置增强处理器->实例化对象(此时只是在内存中开辟空间,属性尚未赋值)->属性填充->回调Aware接口的实现类->执行PostProcessor接口的初始化前方法->执行初始化方法->执行PostProcessor接口的初始化后方法(正常来说在初始化后中进行动态代理)->销毁流程。
本文深入探讨了Spring中的IoC控制反转特性,重点解析了`refresh()`方法在Bean生命周期中的作用。从创建BeanFactory到初始化Bean,包括BeanDefinition的解析、BeanFactoryPostProcessor的后置增强、BeanPostProcessor的使用、Aware接口的应用以及Bean的初始化和销毁过程。通过这个过程,我们了解了Spring如何管理Bean的整个生命周期。
886

被折叠的 条评论
为什么被折叠?



