Spring源码笔记
Spring
Version:5.1.12
ApplicationContext
常用的实例化方式:
- ClassPathXmlApplicationContext
- FileSystemXmlApplicationContext
- XmlWebApplicationContext
通过Spring源码可见多钟方式进行实例化:
ClassPathXmlApplicationContext 比较常用的方式,通过加载xml文件实例化Spring容器,加载bean。
继承结构;
ClassPathXmlApplicationContext:
FileSystemXmlApplicationContext:
XmlWebApplicationContext:
Spring容器初始化过程
通过ClassPathXmlApplicationContext构造方法,调用了其父级AbstractXmlApplicationContext类中的refresh()方法;
1 public ClassPathXmlApplicationContext( 2 String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) 3 throws BeansException { 4 //初始化父级容器 5 super(parent);
6 setConfigLocations(configLocations); 7 if (refresh) { 8 refresh(); //初始化工作 9 } 10 }
Spring容器初始化核心方法是refresh();该方法进行了准备环境、初始化容器、执行bean实例化、通知事件等操作。
refresh():
1 public void refresh() throws BeansException, IllegalStateException { 2 //该锁用于防止refresh和destory()同事进行 3 synchronized (this.startupShutdownMonitor) { 4 //容器初始化前,准备工作: 5 //设置状态、启动时间、实例化配置文件、准备环境 6 prepareRefresh(); 7 8 // 获得beanFactory 9 /** 10 * 初始化DefaultListableBeanFactory beanFactory = createBeanFactory(); 11 * getInternalParentBeanFactory() -- > getParent() --> return this.parent; this.parent 为null 12 * return new new DefaultListableBeanFactory(); 13 */ 14 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 15 16 // 配置BeanFactory context上下文环境 17 prepareBeanFactory(beanFactory); 18 19 try { 20 //BeanFactoryPostProcessor 后置处理操作 21 postProcessBeanFactory(beanFactory); 22 23 // 调用注册过的 BeanFactoryPostProcessor的相关方法 24 invokeBeanFactoryPostProcessors(beanFactory); 25 26 // 注册BeanPostProcessor 27 registerBeanPostProcessors(beanFactory); 28 29 //初始化国际化信息 30 initMessageSource(); 31 32 // 初始化事件 33 initApplicationEventMulticaster(); 34 35 // 调用子类实现的onRefresh方法 36 onRefresh(); 37 38 // 注册监听 39 registerListeners(); 40 41 // 初始化bean操作、注入属性、调用BeanPostProcessor后置处理器方法 42 finishBeanFactoryInitialization(beanFactory); 43 44 // 完成容器加载、执行通知事件 45 finishRefresh(); 46 } 47 catch (BeansException ex) { 48 if (logger.isWarnEnabled()) { 49 logger.warn("Exception encountered during context initialization - " + 50 "cancelling refresh attempt: " + ex); 51 } 52 destroyBeans(); 53 54 cancelRefresh(ex); 55 throw ex; 56 } 57 finally { 58 resetCommonCaches(); 59 } 60 } 61 }
Spring容器简单描述可认为是一个BeanFactory,BeanFactory为一个顶层接口,Spring针对该接口作了大量的实现操作,不同的操作和功能通过大量的子类来进行实现;
Bean加载和初始化
在refresh方法中,Spring对Bean的加载和初始化分开进行,先加载bean的定义loadBeanDefinitions(),在最后才执行bean加载的操作为finishBeanFactoryInitialization();
bean的加载的方式有多种,上面提到的不同方式的容器子类,有classPath(xml方式) 、FileSystem(文件方式)、xmlWeb(远程加载xml)、Annotation(注解,SpringBoot的主要方式)等
Bean信息加载过程:
Bean实例化,finishBeanFactoryInitialization(),通过BeanDefinition Map中的信息逐个创建对象。ConfigurableListableBeanFactory.preInstantiateSingletons()该方法实例化所有懒加载的单例对象。由于懒加载的对象在使用时才根据BeanDefinition信息创建对象。对于scop ="prototype"的对象,Spring只负责创建,不负责管理,所以Spring容器初始化时没有创建懒加载和非单例对象。
Bean创建过程:
Spring循环依赖
目前Spring只支持单例bean通过Set方法和@Autowired注解的方式进行循环依赖。因为Spring通过构造来创建对象。在对象创建完成之后才进行属性设置。
FactoryBean
工厂Bean,接口类
1 public interface FactoryBean<T> { 2 //返回FactoryBean创建的bean实例,isSingleto返回true,则放入到Spring单例池中。 3 T getObject() throws Exception; 4 //返回FactoryBean创建的bean类型 5 Class<?> getObjectType(); 6 //是否单例 7 boolean isSingleton(); 8 9 }
未完待续。。。。。。。