spring初始化源码代码浅析
前言
在《spring初始化源码浅析之关键类和扩展接口》中主要是关键类和扩展接口的介绍,本文主要是debug代码来看spring是如何初始化以及在分别在何时输出上文 demo中各扩展点的日志。
本文分为两部分:《spring初始化源码浅析之关键类和扩展接口》、《spring初始化源码浅析之代码浅析》
1、refresh()简介
通过ClassPathXmlApplicationContext构造方法进入 refresh方法
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //容器刷新前做一些准备工作 prepareRefresh(); // 创建DefaultListableBeanFactory对象,解析出所有BeanDefinition信息, //注册缓存在DefaultListableBeanFactory的beanDefinitionMap属性中,供后面创建bean对象时使用 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 为beanFactory提供一些标准配置,如:类加载器、环境变量等 prepareBeanFactory(beanFactory); try { // 为beanFactory提供一些个性配置,通过在子上下文中复写该方法来实现 postProcessBeanFactory(beanFactory); //创建实现BeanFactoryPostProcessor的实现类,并执行接口的方法。 //该方法执行完后会输出实例中的1-7步的日志 invokeBeanFactoryPostProcessors(beanFactory); //创建BeanPostProcessor的实现类,并注册到BeanFactoryPostProcessor的beanPostProcessors列表中, //在后面创建普通非lazy对象时会遍历该列表回调前置和后置方法 registerBeanPostProcessors(beanFactory); //跟国际化消息相关,没去研究过 initMessageSource(); //初始化该上下文的事件广播 initApplicationEventMulticaster(); //模板方法,在不同的容器刷新的时候可以自定义逻辑 onRefresh(); //创建ApplicationListener的实现类,并注册到该上下文中 registerListeners(); //完成所有剩余的非lazy的bean的创建 finishBeanFactoryInitialization(beanFactory); //上下文的创建完成的一些设置和缓存清理,并发布创建完成事件 finishRefresh(); }catch (BeansException ex) { …… }finally { //Reset common introspection caches in Spring's core, since we //might not ever need metadata for singleton beans anymore... resetCommonCaches(); } }
2、关键代码跟踪
先看《spring初始化源码浅析之关键类和扩展接口》文中代码执行结果:
2.1、obtainFreshBeanFactory()代码分析
首先找到beanFactory的入口方法,如下
继续debug进入refreshBeanFactory方法,如下
从下图中可以看到,XmlBeanDefinitionReader为加载BeanDefinition的关键类,而将beanFactoy作为构造参数主要是为了将创建好的BeanDefinition对象注册到beanFactory中,后面会贴出相应的代码,如下
继续断点进入XmlBeanDefinitionReader的loadBeanDefinitions方法,可见入参为main方法中的指定配置文件的名称,如下
断点继续走,跳过将applicationContext.xml文件解析成Document的过程,进入registerBeanDefinitions(Document doc, Resource resource)方法,入参为applicationContext.xml对应的Document对象,该方法构造一个BeanDefinitionDocumentReader对象来具体的负责从doc对象创建BeanDefinition对象,并注册到beanFactory中,如下
注意 BeanDefinitionDocumentReader的registerBeanDefinitions方法一个入参为XmlReaderContext对象,该对象的reader即为前面创建XmlBeanDefinitionReader对象。
继续断点进入以下方法:
最后进入DefaultListableBeanFactory的registerBeanDefinition方法,最后将创建好的BeanDefinition对象缓存到DefaultListableBeanFactory的一个ConcurrentHashMap中
最终将配置文件中所有的bean配置转成BeanDefinition对象缓存起来,供后面创建具体的bean对象使用。
2.2、invokeBeanFactoryPostProcessors(beanFactory)代码分析
进入方法发现逻辑都交给PostProcessorRegistrationDelegate类来处理:
断点一直走到下面方法,先尝试从单利的缓存中去找,找不到再通过单例工厂类创建对象:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { ……………… singletonObject = singletonFactory.getObject(); newSingleton = true; ………… if (newSingleton) { //添加到单例缓存中 addSingleton(beanName, singletonObject); } } return singletonObject; } } //由于缓存单例对象的 hashmap没有hellword对象,进入singletonFactory.getObject()方法 , //继续断点到 AbstractAutowireCapableBeanFactory的doCreateBean放法 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //创建bean对象的包装器,beanName=hellowordService, //该方法执行完成后输出第一步日志:1->HelloWorldService constructor instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance();//创建bean对象 ………… try { //从RootBeanDefinition 获取属性信息并填充到instanceWrapper对象 populateBean(beanName, mbd, instanceWrapper); //进入初始化bean对象的操作 exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } ………… //将创建好的bean对象注册到缓存起来 registerDisposableBeanIfNecessary(beanName, bean, mbd); } ………… protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // 开始调用各种ware接口的方法,会输出2、3、4步的日志 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //执行BeanPostProcessor的前置方法postProcessBeforeInitialization,由于 //ApplicationContextAwareProcessor实现该接口,该类中会执行很多*Aware的类,而hellwordService //实现ApplicationContextAware类,所在会输出:4->ApplicationContextAware.setApplicationContext: wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //init bean对象 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //执行BeanPostProcessor的后置方法postProcessAfterInitialization, wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { //日志输出 2->BeanNameAware.setBeanName:helloWorldService ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { //日志输出 3->BeanFactoryAware.setBeanFactory: ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } } ………… protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isTraceEnabled()) { logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((InitializingBean) bean).afterPropertiesSet(); return null; }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { //日志输出:5->InitializingBean.afterPropertiesSet ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null && bean.getClass() != NullBean.class) { String initMethodName = mbd.getInitMethodName(); if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { //执行自定义init method方法,输出日志 :6->init method invokeCustomInitMethod(beanName, bean, mbd); } } } }
最后回到getSingleton方法:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { …… //添加到单例缓存中 addSingleton(beanName, singletonObject); }
hellwordService对象创建完毕后,便执行 下一步的invokeBeanFactoryPostProcessors方法,输出第7步日志:
7->BeanFactoryPostProcessor.postProcessBeanFactory 将peopleService的content属性修改为i am ok
到此为止,invokeBeanFactoryPostProcessors(beanFactory);执行完毕
2.3、registerBeanPostProcessors(beanFactory)代码分析
可以看到代码和invokeBeanFactoryPostProcessors(beanFactory)的代码模式几乎一样,在本方法中会创建所有实现BeanPostProcessor接口类并注册到beanFactory中供后面对象创建时回调,代码不再做分析
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
2.4、registerListeners();代码分析
protected void registerListeners() { // Register statically specified listeners first. for (ApplicationListener<?> listener : getApplicationListeners()) { //hellowordService便在此处注册 getApplicationEventMulticaster().addApplicationListener(listener); } ………… }
2.5、finishBeanFactoryInitialization(beanFactory)代码分析
断点直接进入一下代码:
public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { //所有非lazy对象便在此处创建,如实例中的peopleServcie,对象创建过程前面已分析 //peopleServcie的创建过程回掉beanpostProcessors的前置和后置方法,输出日志: //8->BeanPostProcessor.postProcessBeforeInitialization->peopleService //9->BeanPostProcessor.postProcessAfterInitialization->peopleService getBean(beanName); } } } ………… }
2.4、finishRefresh()代码分析
protected void finishRefresh() { // Clear context-level resource caches (such as ASM metadata from scanning). clearResourceCaches(); // Initialize lifecycle processor for this context. initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. getLifecycleProcessor().onRefresh(); // Publish the final event. //发布ContextRefreshedEvent事件,输入日志 //10->ApplicationListener.onApplicationEvent: publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }
到此代码分析完毕,以上只是简要的分析了初始化过程中关键代码,还有很多细节大家可自己断点跟踪。
总结
到此这篇关于spring初始化源码代码浅析的文章就介绍到这了,更多相关spring初始化源码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
java面试散列表及树所对应容器类及HashMap冲突解决全面分析
这篇文章主要介绍了java面试中的java散列表及树所对应容器类与HashMap冲突解决的问题总结,有需要的朋友可以借鉴参考下,希望能够有所帮助2021-10-10java使用lambda表达式对List集合进行操作技巧(JDK1.8)
这篇文章主要介绍了java使用lambda表达式对List集合进行操作技巧适用jdk1.8,感兴趣的朋友跟着小编一起看看实现代码吧2018-06-06springboot如何重定向携带数据 RedirectAttributes
这篇文章主要介绍了springboot如何重定向携带数据 RedirectAttributes,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-09-09
最新评论