Spring源码学习12

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()事件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值