1.留给子类扩展的方法onRefresh();根据注释我们了解到他是想TODO 留给子类初始化其他特殊bean
/**
* Template method which can be overridden to add context-specific refresh work.
* Called on initialization of special beans, before instantiation of singletons.
* 模板方法,可以重写以添加特定于上下文的刷新工作。在实例化单例之前调用特殊bean的初始化。
* <p>This implementation is empty.
* @throws BeansException in case of errors
* @see #refresh()
*/
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
2.registerListeners();该方法用于检查并注册监听器
/**
* 添加那些实现ApplicationListener接口的beans作为监听器
* 那些不是通过beans添加的,不会影响到其他监听器。
*
*/
protected void registerListeners() {
// 首先注册静态指定的侦听器,通过硬编码方式注册的监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 可以看到在这里添加的监听器都是bean的名称,这是因为要保留常规的bean未初始化
// 以至于可以使用post-processors处理他们
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
//添加监听器的beanName
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 现在我们已经有了multicaster和监听器那么我们可以将早就有的事件发布出去了
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
根据上面代码我们不难看出,ApplicationListeners注册方式有两种:
- 方式一:硬编码方式
- 方式二:通过xml配置进去;需要注意的是,通过xml方式配置的监听器并没有实例化,这是保存了beanName,这是为了后面应用后置处理器的处理
然后就是将事先产生的event通过multicaster广播给每个监听器
3.finishBeanFactoryInitialization(beanFactory);初始化剩下的(非延迟加载)的单例beans;为什么说是剩下的,因为有些bean比如那些实现BeanFactoryPostProcessor 和BeanPostProcessor的bean已经初始化了
/**
* .完成此上下文的bean工厂的初始化,初始化所有剩余的单例bean
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 为上下文初始化conversionService参考ConversionServiceFactoryBean
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 如果前面没有类似的PropertyPlaceholderConfigurer bean后处理器
// 则注册一个默认的,主要用于解析注释的@value属性
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 尽早初始化LoadTimeWeaverAware bean以允许尽早注册其变换器。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时的ClassLoader做类型匹配
beanFactory.setTempClassLoader(null);
// 允许缓存所有bean定义元数据,而不期望进一步的更改。
// 设置configurationFrozen为true
// 保存beanName到frozenBeanDefinitionNames,
beanFactory.freezeConfiguration();
//实例化所有剩余(非延迟初始化)单例。
beanFactory.preInstantiateSingletons();
}
a.setConversionService(),类似PropertyEditor用于做属性转换的,使用ConversionServiceFactoryBean注册实现Coverter接口的Coverter比如:
编写String2DateCoverter实现Coverter接口
/**
* @author 周宁
* @Date 2019-07-19 10:47
*/
public class String2DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = sdf.parse(source);
} catch (ParseException e) {
return null;
}
return date;
}
}
编写HaveDateBean.java
/**
* @author 周宁
* @Date 2019-07-19 10:54
*/
public class HaveDateBean {
private Date date;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
通过ConversionServiceFactoryBean注册String2DateCoverter
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="org.springframework.study.day10.String2DateConverter"/>
</list>
</property>
</bean>
<bean id="a" class="org.springframework.study.day10.HaveDateBean">
<property name="date" value="2019-12-12"/>
</bean>
</beans>
测试
@Test
public void testConversionService(){
ApplicationContext ac = new ClassPathXmlApplicationContext("conversionServiceTest.xml");
HaveDateBean haveDateBean = ac.getBean(HaveDateBean.class);
System.out.println(haveDateBean.getDate());
}
b.我们进入实例化bean的方法beanFactory.preInstantiateSingletons()
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// 拷贝一份beanDefinitionNames的副本
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// 触发所有非惰性单例bean的初始化...
for (String beanName : beanNames) {
//合并bean的定义
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//bean不是抽象的类 bean是单利的 bean并不是延迟加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//如果是工厂bean
if (isFactoryBean(beanName)) {
//获取工厂bean,此时factory
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
//判断下是否需要初始化bean
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
//如果是SmartFactoryBean并且允许急切加载,则初始化factoryBean
//getObject()方法返回的bean
if (isEagerInit) {
getBean(beanName);
}
}
else {
//非工厂bean直接初始化
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
//获取单例的实例是否 是 SmartInitializingSingleton的子类
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
//调用afterSingletonsInstantiated方法
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
对于该方法有以下几点需要说明:
- 1.对于FacoryBean,只会初始化FactoryBean实例,不会实例化调用FactoryBean中getObject()的实例。但是可以通过实现SmartFactoryBean接口去实例化FactoryBean的getObject()中的实例
- 2.在实例化所有单例bean后,会判断bean实例是否实现了SmartInitializingSingleton接口,并应用afterSingletonsInstantiated方法
/**
* 在{@link BeanFactory}引导期间,在单例预实例化阶段结束时触发了回调接口。
* 此接口可以由单例bean实现,以便在常规单例实例化算法之后执行一些初始化,
* 避免意外早期初始化的副作用(例如来自{@link ListableBeanFactory#getBeansOfType}调用).
* 从某个意义上来说他是在bean本地构建阶段结束触发的{@link ListableBeanFactory#getBeansOfType}
* 替代
*
* <p>此回调变体有点类似于{@link org.springframework.context.event.ContextRefreshedEvent},
* 但不需要{@link org.springframework.context.ApplicationListener的实现
* 无需跨上下文层次结构等过滤上下文引用.
* 它还意味着对{@code beans}包的依赖性更小,并且受到独立的{@link ListableBeanFactory}实现的尊重,
* 而不仅仅是在{@link org.springframework.context.ApplicationContext}环境中。
*
* <p><b>NOTE:</b> 注意:</ b>如果您打算启动/管理异步任务,
* 最好实现{@link org.springframework.context.Lifecycle},它为运行时管理提供了更丰富的模型,并允许分阶段启动/关闭
*
* @author Juergen Hoeller
* @since 4.1
* @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons()
*/
public interface SmartInitializingSingleton {
/**
* 在单例预实例化阶段结束时调用,
* 保证所有常规单例的bean都已经已创建
* 在引导期间的{@link ListableBeanFactory#getBeansOfType}调用
* 不会触发意外的副作用
* <p><b>NOTE:</b> This callback won't be triggered for singleton beans
* lazily initialized on demand after {@link BeanFactory} bootstrap,
* and not for any other bean scope either. Carefully use it for beans
* with the intended bootstrap semantics only.
* 这个回调对于{@link BeanFactory}的引导命令的延迟加载的单例beans不会触发
* 而且也不适用于任何其他bean范围。 小心地将它用于beans
* 仅具有预期的引导语义
*/
void afterSingletonsInstantiated();
4.DefaultLifecycleProcessor的UML类图
Lifecycle:定义启动/停止生命周期控制方法的通用接口。主要有start()、stop()、isRunning()方法
LifecycleProcessor:用于在ApplicationContext中处理Lifecycle bean的策略接口;扩展了Lifecycle接口,扩展方法onRefresh()上下文刷新通知、onClose()上下文关闭通知,比如停止组件
DefaultLifecycleProcessor:LifecycleProcessor默认的实现,主要是实现了onRefresh()、onStop(),用于处理那些实现了Lifecycle接口的bean。
5.finishRefresh()方法;完成此上下文的刷新,调用LifecycleProcessor的onRefresh()方法并发布{@link org.springframework.context.event.ContextRefreshedEvent}事件
/**
* 完成此上下文的刷新,调用LifecycleProcessor的
* onRefresh()方法并发布{@link org.springframework.context.event.ContextRefreshedEvent}
* 事件
*
* .
*/
protected void finishRefresh() {
//为此上下文初始化生命周期处理器。
// 给AbstractApplicationContext的lifecycleProcessor
// 赋值默认的DefaultLifecycleProcessor
// 可以自己实现自定义的
initLifecycleProcessor();
// 首先将刷新传播到生命周期处理器。
//
getLifecycleProcessor().onRefresh();
// Publish the final event.
// 发布最终活动。
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
//
LiveBeansView.registerApplicationContext(this);
}
a.initLifecycleProcessor()实现如下:就是看看用户有没有自定的LifecycleProcessor,没有使用默认的
/**
* 初始化LifecycleProcessor.Uses DefaultLifecycleProcessor如果在上下文中没有定义。
* @see org.springframework.context.support.DefaultLifecycleProcessor
*/
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isDebugEnabled()) {
logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate LifecycleProcessor with name '" +
LIFECYCLE_PROCESSOR_BEAN_NAME +
"': using default [" + this.lifecycleProcessor + "]");
}
}
}
b.调用LifecycleProcessor的onfresh方法
@Override
public void onRefresh() {
startBeans(true);
this.running = true;
}
private void startBeans(boolean autoStartupOnly) {
//获取LifecycleBeans
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
Lifecycle bean = entry.getValue();
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
//给定bean的生命周期阶段
int phase = getPhase(bean);
LifecycleGroup group = phases.get(phase);
if (group == null) {
group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
phases.put(phase, group);
}
group.add(entry.getKey(), bean);
}
}
//按阶段分组后的bean不为空
if (!phases.isEmpty()) {
//按照阶段的优先级从小到大启动
List<Integer> keys = new ArrayList<Integer>(phases.keySet());
Collections.sort(keys);
for (Integer key : keys) {
phases.get(key).start();
}
}
}
我们分析下startBeans方法,无非就是获取到所有实现了Lifecycle接口的Bean,然后按照某个值分组,这个值可以通过实现Phased(可以理解为用于设置start顺序)接口设置,对于没有实现Phased接口的bean默认的值为0,对于分组后的bean按Phased设置的值的大小从小到大的分组值批量启动
public void start() {
if (this.members.isEmpty()) {
return;
}
if (logger.isInfoEnabled()) {
logger.info("Starting beans in phase " + this.phase);
}
Collections.sort(this.members);
for (LifecycleGroupMember member : this.members) {
if (this.lifecycleBeans.containsKey(member.name)) {
doStart(this.lifecycleBeans, member.name, this.autoStartupOnly);
}
}
}
/**
* 将指定的bean作为给定生命周期bean集的一部分启动,
* 确保首先启动它依赖的任何bean。
* @param lifecycleBeans a Map with bean name as key and Lifecycle instance as value
* @param beanName the name of the bean to start
*/
private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
Lifecycle bean = lifecycleBeans.remove(beanName);
if (bean != null && bean != this) {
//bean 依赖到的bean 递归启动下来
String[] dependenciesForBean = this.beanFactory.getDependenciesForBean(beanName);
for (String dependency : dependenciesForBean) {
doStart(lifecycleBeans, dependency, autoStartupOnly);
}
// bean 未在运行中
if (!bean.isRunning() &&
//非自动启动 bean 不是SmartLifecycle类型 或者SmartLifecycle 类型的自动bean
(!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
if (logger.isDebugEnabled()) {
logger.debug("Starting bean '" + beanName + "' of type [" + bean.getClass().getName() + "]");
}
try {
bean.start();
}
catch (Throwable ex) {
throw new ApplicationContextException("Failed to start bean '" + beanName + "'", ex);
}
if (logger.isDebugEnabled()) {
logger.debug("Successfully started bean '" + beanName + "'");
}
}
}
}
c.发布ContextRefreshedEvent()事件