4 在bean factory中创造 bean
写在前面:该 part 是 Spring ioc 的核心,显得非常冗杂,Spring 内不知名的组件非常的多,有很多笔者也难以描述清楚,甚至也没见过。在介绍的时候会做适当的忽略。
该 part 的起点:
public AnnotationConfigApplicationContext(Class ... annotatedClasses) { this(); register(annotatedClasses); refresh(); // 4 在 bean factory 中创造 bean}
来追踪这个方法的实现:
//AbstractApplicationContext.classpublic void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //准备工作的配置 //4.3 prepareRefresh(); //获取 bean factory //4.4 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //配置 bean factory //4.5 prepareBeanFactory(beanFactory); try { //4.6 postProcessBeanFactory(beanFactory); //4.7 invokeBeanFactoryPostProcessors(beanFactory); //4.8 registerBeanPostProcessors(beanFactory); //4.9 initMessageSource(); //4.10 initApplicationEventMulticaster(); //4.11 onRefresh(); //4.12 registerListeners(); //4.13 finishBeanFactoryInitialization(beanFactory); //4.15 finishRefresh(); }catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } //4.16 destroyBeans(); //4.17 cancelRefresh(ex); throw ex; }finally { //4.18 resetCommonCaches(); } }}
4.1
在开始之前先来看一下 BeanPostProcessor:
public interface BeanPostProcessor { //此方法在 bean 初始化之前、bean 的构造方法调用之后执行 @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } //此方法在 bean 初始化之后执行 @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }}
BeanPostProcessor 在 bean 的注册阶段就已经大量接触到了,在下列 bean 的创建阶段会更多的遇到,是 Spring ioc 的重要组成部分。
Spring 容器本身在初始化的时候就会注册很多个 BeanPostProcessor 接口的实现类到 BeanFactory 中。这些类会被 BeanFactory 实例成 bean,并特殊存放到一个列表中。在其它普通 bean 的初始化(即为 init 方法被调用时)之前,轮循 BeanPostProcessor 列表,执行 postProcessBeforeInitialization(...) 方法;在其它普通 bean 的初始化之后,再次轮训 BeanPostProcessor 列表,执行 postProcessAfterInitialization(...) 方法。
从出入参可知,这两个方法用于在 bean 的初始化阶段对 bean 进行功能增强操作,包括但不限于代码织入(asm)、切面操作(aop)等。
作为 Spring 的使用者,只要是自行编写实现了该接口的类,然后通过配置将该类作为 Bean 注册到 Spring 中,就会被 Spring 一视同仁的作为内部 BeanPostProcessor 对待。
4.2
再来看一下创建 bean 的核心方法,即 BeanUtil.instantiateClass(...):
//BeanUtil.classpublic staticT instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException { Assert.notNull(ctor, "Constructor must not be null"); try { //设置 accessible = true,即为去掉 privite 关键词对构造的影响 ReflectionUtils.makeAccessible(ctor); //这个返回语句主要是为了兼容 kotlin 语言,对于 java 来说主要是 ctor.newInstance(args) //本质是调用 bean 的构造器来实例化 bean return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ? KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args)); }catch (InstantiationException ex) { throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex); }catch (IllegalAccessException ex) { throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex); }catch (IllegalArgumentException ex) { throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex); }catch (InvocationTargetException ex) { throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException()); }}
BeanUtil 是 bean 的实例化的关键,Spring 的其它代码都是在做各种判断,但是真正实例化 bean 的就这一句。
4.3
看下方代码片段:
//AbstractApplicationContext.classprotected void prepareRefresh() { //记录下启动时间 this.startupDate = System.currentTimeMillis(); //这两个变量与优雅关闭有关,这里确定 Spring 未关闭 this.closed.set(false); this.active.set(true); //logger 日志相关代码均不作描述了 if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { logger.trace("Refreshing " + this); } else { logger.debug("Refreshing " + getDisplayName()); } } //初始化 property //该方法是空的 initPropertySources(); //检查读取到的 properties 键值对 getEnvironment().validateRequiredProperties(); //新建一个集合,这个集合用于储存需要立即通知的事件 this.earlyApplicationEvents = new LinkedHashSet<>();}
closed 和 active 都是定义在 AbstractApplicationContext 中的 AtomicBoolean,用以管理 Spring 容器的状态:
//容器是否处于活动中private final AtomicBoolean active = new AtomicBoolean();//容器是否已经关闭private final AtomicBoolean closed = new AtomicBoolean();
initPropertySources() 方法其实是一个预留下的空方法:
//AbstractApplicationContext.classprotected void initPropertySources() { }
getEnvironment() 在之前的代码里看到过,用来获取一个新创建出来的 StandardEnvironment 对象,而 validateRequiredProperties() 是定义在 AbstractEnvironment 中的方法:
//AbstractEnvironment.classpublic void validateRequiredProperties() throws MissingRequiredPropertiesException { this.propertyResolver.validateRequiredProperties();}
propertyResolver 是一个定义在 AbstractEnvironment 中的 PropertySourcesPropertyResolver 对象,顾名思义,是用来管理 properties 配置文件中读取到的值的。来看一下 validateRequiredProperties():
//AbstractPropertyResolver.classpublic void validateRequiredProperties() { //新建了一个 Exception,用于在出错情况下进行返回 MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException(); //这里的字面意思上可以看出,这个 for 循环语句用于从 requiredProperties 这个集合里获取每个 properties key for (String key : this.requiredProperties) { //getProperty(key) 方法会用 key 去获取 value 值,然后进行空值比对 if (this.getProperty(key) == null) { //如果存在 null,则加入到错误信息里 ex.addMissingRequiredProperty(key); } } //错误信息不为空,证明上述代码中存在值为 null 的,就直接抛出异常 if (!ex.getMissingRequiredProperties().isEmpty()) { throw ex; }}
4.4
看下方代码片段:
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
追踪 obtainFreshBeanFactory() 方法:
//AbstractApplicationContext.classprotected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); return getBeanFactory();}
追踪 refreshBeanFactory() 方法的内部实现:
//GenericApplicationContext.classprotected final void refreshBeanFactory() throws IllegalStateException { if (!this.refreshed.compareAndSet(false, true)) { //抛出错误,提示大意为:已经调用过一次 "refresh" 了 throw new IllegalStateException( "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); } //存入一个用于序列化的 id this.beanFactory.setSerializationId(getId());}
refreshed 是一个定义在 GenericApplicationContext 中的 AtomicBoolean 类型对象。AtomicBoolean 的 compareAndSet(...) 方法等同于进行如下操作:
//比较 AtomicBoolean 当前的值和第一个参数是否相等,如果一致,则将 AtomicBoolean 当前的值换成第二个值。//以下为模拟代码,AtomicBoolean 的真实实现大多数是使用虚拟机底层代码完成,是原子化的操作if(atomicBoolean == false){ atomicBoolean = true; return true;}else{ return false;}
this.beanFactory.setSerializationId(getId()) 会将 AbstractApplicationContext 内的 id 存入一个定义在 DefaultListableBeanFactory 中的 map 对象里。
4.5
看下方代码片段:
prepareBeanFactory(beanFactory);
追踪代码实现:
//AbstractApplicationContext.classprotected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //存入 AnnotationConfigApplicationContext 中的 classLoader beanFactory.setBeanClassLoader(getClassLoader()); //StandardBeanExpressionResolver 用于解析 Spring EL 表达式的解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //ResourceEditorRegistrar 用于各种 bean 与 String 之间进行转换的属性编辑器 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //ApplicationContextAwareProcessor 用于注入各类 aware bean beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //在自动装配(autowire)阶段要忽略的接口类 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); //自动装配的规则 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); //ApplicationListenerDetector 用于类型是 ApplicationListener 的bean添加到事件广播器 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); //代码动态织入 //LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver" if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { //LoadTimeWeaverAwareProcessor 用于在 bean 初始化之前检查 bean 是否实现了LoadTimeWeaverAware 接口 //与 Spring aop 代码织入相关的 BeanPostProcessor beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); //用于类型匹配的 classloader beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } //注册 properties 和 environment 相关的 bean //这里不仅会注册,而且会直接将这些 bean 存放到 singleObject 中(即为直接实例化出来) if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); }}
代码动态织入是 Spring 底层 cglib 的相关概念,暂时不展开。
4.6
看下方代码片段:
postProcessBeanFactory(beanFactory);
在 AbstractApplicationContext 中该方法是一个空方法:
//AbstractApplicationContext.classprotected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {}
该方法预留给 AbstractApplicationContext 的子类去实现,目的是在 bean factory 装配完成之后做一些定制化处理 AbstractApplicationContext。在 AnnotationConfigApplicationContext 及其父类中没有重写该方法。
4.7
看下方代码片段:
invokeBeanFactoryPostProcessors(beanFactory);
追踪代码实现:
//AbstractApplicationContext.classprotected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }}
这段代码和上述 4.4 中的一段几乎是一摸一样的,Spring 在这里做了二次验证。
4.8
看下方代码片段:
registerBeanPostProcessors(beanFactory);
从字面意思可以看出就是在 beanFactory 中注册 BeanPostProcessor。注册的本质是将 BeanPostProcessor 保存到一个列表里。从源码里看,该列表是定义在 AbstractBeanFactory 中的 beanPostProcessors。
追踪代码实现:
//AbstractApplicationContext.classprotected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}
继续追踪:
//PostProcessorRegistrationDelegate.classpublic static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { //根据 class 获取到所有符合的 bean,即 BeanPostProcessor 的子类 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); //beanFactory.getBeanPostProcessorCount() 获取到的数字是在 4.4 中 set 的 BeanPostProcessor 的数量 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; //BeanPostProcessorChecker 是 PostProcessorRegistrationDelegate 的私有静态内部类 //如果一个 bean 没有被所有的 BeanPostProcessor 处理完毕,BeanPostProcessorChecker 就会打印日志 beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); //处理 Order 相关接口 //Order 是一个用于排序的接口 //用于存放实现了 PriorityOrdered 接口的 BeanPostProcessor ListpriorityOrderedPostProcessors = new ArrayList<>(); //用于存放实现了 MergedBeanDefinitionPostProcessor 接口的 BeanPostProcessor List internalPostProcessors = new ArrayList<>(); //用于存放实现了 Ordered 接口的 BeanPostProcessor List orderedPostProcessorNames = new ArrayList<>(); //其它 BeanPostProcessor List nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { //isTypeMatch(...) 方法会判断该名称的 bean 和 class 类型是否一致 //这里查看是否实现了 PriorityOrdered 接口 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //获取 bean 并添加到一个列表中 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { //继续判断是否实现了 MergedBeanDefinitionPostProcessor 接口 internalPostProcessors.add(pp); } }else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { //如果并非实现了 PriorityOrdered 接口就判断是否实现了 Ordered 接口 orderedPostProcessorNames.add(ppName); }else { //均无,则存入 nonOrderedPostProcessorNames 列表中 nonOrderedPostProcessorNames.add(ppName); } } //对于实现了 PriorityOrdered 接口的 BeanPostProcessor 进行排序 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); //依次注册这些 BeanPostProcessor registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); //下方代码块和上方很雷同,注册实现了 Ordered 接口的 BeanPostProcessor List orderedPostProcessors = new ArrayList<>(); for (String ppName : orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); //注册没有实现任何排序接口的 BeanPostProcessor List nonOrderedPostProcessors = new ArrayList<>(); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); //对于实现了 MergedBeanDefinitionPostProcessor 接口的 BeanPostProcessor 会统一进行排序并注册 sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); //ApplicationListenerDetector 用于在 bean 初始化后检查是否实现了 ApplicationListener 接口 //从代码来看,实现了该接口的 bean 会被存入一个叫 applicationListeners 的列表中 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}
综合来看这个方法的主体是对 BeanPostProcessor 进行依次的存储(会影响到 BeanPostProcessor 的执行顺序)。
次序的依据主要是看这些 BeanPostProcessor 是否实现了 Order 及其相关的接口。
4.9
看下方代码片段:
initMessageSource();
追踪代码实现:
//AbstractApplicationContext.classprotected void initMessageSource() { //获取 beanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //MESSAGE_SOURCE_BEAN_NAME = "messageSource" //先去查看 beanFactory 中是否有该名称的 bean if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { //获取到这个 bean this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); //主体思路是将数据源存入这个 bean 中 if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; if (hms.getParentMessageSource() == null) { //存入默认的数据源 //getInternalParentMessageSource() 方法会先 hms.setParentMessageSource(getInternalParentMessageSource()); } } if (logger.isTraceEnabled()) { logger.trace("Using MessageSource [" + this.messageSource + "]"); } }else { //没有这个 bean 的情况下就自定义一个,并存入到 beanFactory 中 DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); if (logger.isTraceEnabled()) { logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]"); } }}
Spring 中可以配置多套配置文件,之间通过 messageSource 进行切换。
4.10
看下方代码片段:
initApplicationEventMulticaster();
追踪代码实现:
//AbstractApplicationContext.classprotected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster" //检查是否存在名称为 applicationEventMulticaster 的 bean if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { //如果存在则赋值给 applicationEventMulticaster this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isTraceEnabled()) { logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } }else { //没有的话就创建一个,并注册与赋值 this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isTraceEnabled()) { logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " + "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]"); } }}
applicationEventMulticaster 是一个观察者模式的应用,可以理解为是用来分发数据给监听器(Listener)的中转站。
4.11
看下方代码片段:
onRefresh();
默认该方法为空:
//AbstractApplicationContext.classprotected void onRefresh() throws BeansException {}
预留用于处理特殊的 bean。
4.12
registerListeners();
追踪代码实现:
//AbstractApplicationContext.classprotected void registerListeners() { //遍历 applicationListeners 列表 //往 applicationEventMulticaster 内部的列表 applicationListeners 里添加 //applicationListener 用于在容器初始化时期监听事件 for (ApplicationListener listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } //获取可能存在的使用者自行定义的监听器,同样添加到列表里 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } //获取所有的 event,放到一个列表里 SetearlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } }}
特定的监听器用于监听某一类的 event,在容器启动时生效,对 event 做出处理。
监听器被储存在 applicationEventMulticaster 中,发生事件的时候被告知。
4.13
finishBeanFactoryInitialization(beanFactory);
追踪代码实现:
//AbstractApplicationContext.classprotected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //CONVERSION_SERVICE_BEAN_NAME = "conversionService" //conversionService 这个 bean 用于映射数据类型,比如将前端的字符串类型数据转成日期等 //由使用者自主实现并配置,默认情况下没有这个 bean 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)); } //如果 beanFactory 里没有 embeddedValueResolver,就会从 environment 里获取并加载到里面 //embeddedValueResolver 是和配置文件读取相关的组件 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver((strVal) -> { return this.getEnvironment().resolvePlaceholders(strVal); }); } //以下代码用于提前实例化代码织入相关的 bean String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); String[] var3 = weaverAwareNames; int var4 = weaverAwareNames.length; for(int var5 = 0; var5 < var4; ++var5) { String weaverAwareName = var3[var5]; this.getBean(weaverAwareName); } //将 classLoader 置空,因为已经用不到了,所以清除掉,节省内存 beanFactory.setTempClassLoader((ClassLoader)null); //这个方法会将 beanName 列表转换成一个字符串数组,节省内存 beanFactory.freezeConfiguration(); //实例化 bean 的核心方法 beanFactory.preInstantiateSingletons();}
来看一下 beanFactory.preInstantiateSingletons() 方法:
//DefaultListableBeanFactory.classpublic void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } //将 beanName 列表拷贝一份 ListbeanNames = new ArrayList<>(this.beanDefinitionNames); //遍历 for (String beanName : beanNames) { //获取每个 bean RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //需要最终确认 bean 不是抽象类,且为单例的,且不是惰性加载的 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //判断其是否实现了 FactoryBean 接口 //FactoryBean 是 Spring 留出的可供使用者选择的用于生产 bean 的工厂模式接口 if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //二次判断 if (bean instanceof FactoryBean) { final FactoryBean factory = (FactoryBean ) bean; //是否期望被 init boolean isEagerInit; //系统存在权限问题的时候才会进入到这个判断语句中 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { //AccessController.doPrivileged(...) 方法用于 java 的权限控制 //此处调用了此方法用于剔除权限对 Spring 的控制 //此处与下方代码都调用了 SmartFactoryBean 接口的 isEagerInit() 方法进行判断 isEagerInit = AccessController.doPrivileged((PrivilegedAction ) ((SmartFactoryBean ) factory)::isEagerInit, getAccessControlContext()); }else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean ) factory).isEagerInit()); } //实例化 if (isEagerInit) { getBean(beanName); } } }else { //其实对于绝大多数普通的 bean,是直接调用这个语句进行实例化的 getBean(beanName); } } } //此处再次循环获取 bean ,用于对实现了 SmartInitializingSingleton 接口的 bean 进行特殊操作 //SmartInitializingSingleton 接口内有一个 afterSingletonsInstantiated() 方法,会在完成 bean 的实例化之后执行 for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
4.14
所以最终实例化 bean 的是 getBean(...) 方法,此方法不仅可以用于从容器中取出 bean,也是实例化 bean 的具体实现。
追踪其具体代码实现:
//AbstractBeanFactory.classpublic Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false);}
继续来看 doGetBean(...) 方法:
//AbstractBeanFactory.classprotectedT doGetBean(final String name, @Nullable final Class requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; //对于之前已经实例过的 bean,会在这个方法里获取到 //如果没有实例化过,那么此处获取的是 null Object sharedInstance = getSingleton(beanName); //args 是用于实例化 bean 过程中传入构造器的参数 //此处传入的 args 为 null if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); }else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } //此方法用于处理 FactoryBean 的情况,如果没有的话是直接返回 sharedInstance 的 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }else { //如果 bean 正在创建,会抛出异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //先取出父类中存放的 parentBeanFactory,如果有实现的话就用该工厂来创建 bean //本例中没有使用 parentBeanFactory BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); }else if (args != null) { return (T) parentBeanFactory.getBean(nameToLookup, args); }else if (requiredType != null) { return parentBeanFactory.getBean(nameToLookup, requiredType); }else { return (T) parentBeanFactory.getBean(nameToLookup); } } //这里会将 bean 标记为已经创建 if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { //获取 bean 的包装类 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //bean 不能是一个 abstract 修饰的类,否则会报错 checkMergedBeanDefinition(mbd, beanName, args); //depends-on 用来处理要实例化某个 bean,必须先实例化另一个 bean 的情况 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { //处理循环依赖的问题 if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } //注册要依赖的 bean registerDependentBean(dep, beanName); try { //实例化要依赖的 bean getBean(dep); }catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } //是否是单例的 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { //实例化 bean 的核心方法 return createBean(beanName, mbd, args); }catch (BeansException ex) { //如果报错的话会销毁掉这个 bean destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }else if (mbd.isPrototype()) { //如果 scope 注解为 prototype,则每次获取 bean 的时候都会创建新的 bean 实例 Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); }else { //获取 scope 注解的值,如果是 null 的话会报错 String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { //这一步的操作和上方代码块几乎是一样的 Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); }finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); }catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } }catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } //requiredType 是使用者传入的 class 对象,使用者可以将 bean 转换成该类型并输出 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; }catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } //返回 bean return (T) bean;}
继续追踪 createBean(...) 方法:
//AbstractAutowireCapableBeanFactory.classprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; //获取 bean 的 class,然后在再次确定了 bean 的 class 无误之后,克隆一份 bean 并存入 bean class Class resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } //重写的方法解析 try { mbdToUse.prepareMethodOverrides(); }catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //根据注释来看,这个方法是使用 BeanPostProcessor 去进行动态代理 //如果存在对应的 BeanPostProcessor,返回的是动态代理的类,而不是 bean 本身 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } }catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { //实例化 bean 的核心方法 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { throw ex; }catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); }}
继续追踪 doCreateBean(...) 方法:
//AbstractAutowireCapableBeanFactory.classprotected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { //BeanWrapper 是 bean 的另一种包装 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { //factoryBeanInstanceCache 是一个 map 对象,用于缓存 wrapper //此处从缓存中删除并返回此 wrapper instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } //如果没有的话会创建一个 if (instanceWrapper == null) { //这一步会实例化 bean instanceWrapper = createBeanInstance(beanName, mbd, args); } //获取 bean 实例 final Object bean = instanceWrapper.getWrappedInstance(); //获取 class Class beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { //该方法会轮询 BeanPostProcessor 列表进行 bean 的增强操作 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); }catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } //是否是单例,是否允许循环引用,该单例 bean 是否在创建中 //isSingletonCurrentlyInCreation(beanName) 方法会去集合 singletonsCurrentlyInCreation 中搜寻 beanName //如果存在,证明该 bean 正在被初始化,初始化完成之后会从该集合中删除掉,功能相当于锁 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } //将 beanName 注册到 singletonFactories 和 registeredSingletons 中 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } //添加一个 bean 的引用 exposedObject Object exposedObject = bean; try { //该方法会根据配置来填充 mbd 中 populateBean(beanName, mbd, instanceWrapper); //将信息填充到 exposedObject 中 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); } } if (earlySingletonExposure) { //getSingleton(...) 方法的第二个参数代表是否允许循环引用,这里输入的是 false(不允许) //对于一般的 bean,这里获取到的 earlySingletonReference = null Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; }else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); SetactualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } //注册需要执行销毁方法的 bean try { registerDisposableBeanIfNecessary(beanName, bean, mbd); }catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject;}
继续追踪 createBeanInstance(...) 方法:
//AbstractAutowireCapableBeanFactory.classprotected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { //获取到 bean 的 class Class beanClass = resolveBeanClass(mbd, beanName); //如果 class 不为空,且修饰语非 public,且没有设置 accessible = true if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } //如果 BeanDefinition 中有保存 Supplier,则使用该方式去获取 bean //Supplier 是 jdk8 中配合函数式编程所添加的用于获取 bean 的接口 //Supplier 每次获取的 bean 都不是同一个 Supplier instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } //如果有工厂方法,就用工厂方法进行实例化 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { //查看是否缓存了构造器 if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; //这里要判断构造器的参数是否使用了 Autowire 注解 autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { //如果使用了 Autowire 注解就会进入这个方法进行实例化 return autowireConstructor(beanName, mbd, null, null); }else { //常规的实例化 bean return instantiateBean(beanName, mbd); } } //如果一个继承了 BeanPostProcessor 接口的 bean 的构造器参数使用了 Autowire 注解,会在此处单独处理 Constructor [] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } //获取首选的构造器 //在该版本的 RootBeanDefinition 里,该方法没有方法体,直接返回 null //也就是说,该代码是不启用的 ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); } //实例化 bean return instantiateBean(beanName, mbd);}
继续追踪 instantiateBean(...) 方法:
//AbstractAutowireCapableBeanFactory.classprotected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; //再次检测权限环境 //此例中没有涉及 if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged((PrivilegedAction
继续追踪 instantiate(...) 方法:
//SimpleInstantiationStrategy.classpublic Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { //不需要方法重载,就不需要 cglib 帮助了 if (!bd.hasMethodOverrides()) { Constructor constructorToUse; synchronized (bd.constructorArgumentLock) { //先尝试查看 BeanDefinition 中是否保存了构造器,如果没有保存,就在下方从 class 中拿出来 constructorToUse = (Constructor ) bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { final Class clazz = bd.getBeanClass(); if (clazz.isInterface()) { //bean 不能是一个接口 throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { //这里验证权限设置 if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged( (PrivilegedExceptionAction>) clazz::getDeclaredConstructor); }else { //获取构造器 constructorToUse = clazz.getDeclaredConstructor(); } bd.resolvedConstructorOrFactoryMethod = constructorToUse; }catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } //实例化 bean return BeanUtils.instantiateClass(constructorToUse); }else { //使用 cglib 进行 bean 的实例化 return instantiateWithMethodInjection(bd, beanName, owner); }}
此小节是整个实例化 bean 过程中最冗长,也最核心的部分。
这中间 Spring 做了大量的验证和业务判断,但是实际上最终 bean 的实例化并不复杂。
4.15
finishRefresh();
追踪代码实现:
//AbstractApplicationContext.classprotected void finishRefresh() { //清空缓存,即将 resourceCaches 这个 map 对象置空 clearResourceCaches(); //实例化一个类型为 DefaultLifecycleProcessor 的 bean,用于控制 bean 的生命周期 initLifecycleProcessor(); getLifecycleProcessor().onRefresh(); //刷新上下文事件 //ContextRefreshedEvent 并没有业务逻辑 publishEvent(new ContextRefreshedEvent(this)); //此方法会将 applicationContext 保存到 LiveBeansView 中的一个集合内 LiveBeansView.registerApplicationContext(this);}
到此为止,正常的 ApplicationContext 的初始化流程就完成了。
4.16
看下方代码片段:
destroyBeans();
这个方法的实现:
//AbstractApplicationContext.classprotected void destroyBeans() { getBeanFactory().destroySingletons();}
destroySingletons() 是定义在 DefaultListableBeanFactory 中的方法:
//DefaultListableBeanFactory.classpublic void destroySingletons() { super.destroySingletons(); //manualSingletonNames 是一个用来存放已经被创建的单例 bean 的名字的 Set集合 this.manualSingletonNames.clear(); clearByTypeCache();}
这里的 super.destroySingletons() 调用的是其父类 DefaultSingletonBeanRegistry 中的方法:
//DefaultSingletonBeanRegistry.classpublic void destroySingletons() { if (logger.isTraceEnabled()) { logger.trace("Destroying singletons in " + this); } synchronized (this.singletonObjects) { this.singletonsCurrentlyInDestruction = true; } String[] disposableBeanNames; synchronized (this.disposableBeans) { disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); } for (int i = disposableBeanNames.length - 1; i >= 0; i--) { destroySingleton(disposableBeanNames[i]); } this.containedBeanMap.clear(); this.dependentBeanMap.clear(); this.dependenciesForBeanMap.clear(); //清空相关的集合内的引用对象,并且销毁已经创建的 bean clearSingletonCache();}
再来看一下 clearByTypeCache() 方法:
//DefaultListableBeanFactory.classprivate void clearByTypeCache() { this.allBeanNamesByType.clear(); this.singletonBeanNamesByType.clear();}
4.17
看下方代码片段:
cancelRefresh(ex);
这个方法的实现:
//AbstractApplicationContext.classprotected void cancelRefresh(BeansException ex) { //传入的 exception 其实并没有用到 this.active.set(false);}
active 是定义在 AbstractApplicationContext 中的一个 AtomicBoolean:
private final AtomicBoolean active = new AtomicBoolean();
这里将其的值设置为 false。
4.18
看下方代码片段:
resetCommonCaches();
具体实现
//AbstractApplicationContext.classprotected void resetCommonCaches() { //主要是将 util 类里的一些 static 修饰的集合和 map 对象进行置空。 ReflectionUtils.clearCache(); AnnotationUtils.clearCache(); ResolvableType.clearCache(); CachedIntrospectionResults.clearClassLoader(getClassLoader());}
从 4.16 到 4.18 的代码总体都比较简单,就是把各种的相关的集合、map、列表都清空掉,将 bean 的引用对象也都 remove 掉。
实际上是优雅关闭的过程。
二 一点唠叨
· Spring 的代码实在是太庞大了,刚开始想要尽可能详细的去解释每个组件,但是后来觉得难度略大
· Spring 的小部分组件和代码在笔者看来是有些莫名其妙的,且都没有查到详细而合理的解释
· Spring 的代码很明显使用了防御性的编程原则,保证了每个方法都足够健壮,但是同时造成了重复验证和冗余
· Spring 显然非常强调易用性和泛用性,提供了繁多的功能,甚至有部分是显得过于灵活的,如果笔者未读源码大概一辈子都不会知道
· Spring 对组件状态的控制异常复杂且精确
· Spring 对内存的控制很苛刻
· 仅为个人的学习笔记,可能存在错误或者表述不清的地方,有缘补充