diff --git a/README.md b/README.md index 1393abe..a4aa1c9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ ## Spring 源码解析 1. [\[2021-10-09\] SpringMVC 的加载机制](spring/1.md) +1. [\[2021-10-12\] Spring 源码解析二:SpringMVC 的上下文组件(WebApplicationContext)](spring/2.md) +1. [\[2021-10-14\] Spring 源码解析三:SpringMVC 的 Bean 注册、解析、实例化机制](spring/3.md) ## 前端进阶 diff --git a/spring/1.md b/spring/1.md index 872ba03..3e0889f 100644 --- a/spring/1.md +++ b/spring/1.md @@ -46,7 +46,9 @@ SpringMVC 框架的核心模块主要是:`spring-core`、`spring-beans`、`spr Spring bean 的加载与扩展机制有几点需要在这里简单介绍一下: 1. Spring bean 的定义主要是两种:基于注解的定义、基于 XML 文件的定义 -1. `spring-beans` 提供了基于 XML 配置的、第三方对 bean 的自定义扩展机制,主要是在 `META-INF/spring.handlers, META-INF/spring.schemas` 文件中定义需要扩展的标签,比如 `, ` +1. `spring-beans` 提供了基于 XML 配置的、第三方对 bean 的自定义扩展机制,主要是在 + `META-INF/spring.handlers, META-INF/spring.schemas` 文件中定义需要扩展的标签, + 比如 `, ` 1. 基于注解的自定义扩展,需要依赖 `spring-boot` 的扩展加载机制 ### 1.3. `spring-context` @@ -90,9 +92,11 @@ Spring bean 的加载与扩展机制有几点需要在这里简单介绍一下 ### 1.6. `spring-webflux` -`spring-webflux` 与 `spring-webmvc` 相对应,`webmvc` 是同步阻塞框架,而 `webflux` 是异步非阻塞框架,是 Spring Framework 5.0 中引入的新的响应式 web 框架。 +`spring-webflux` 与 `spring-webmvc` 相对应,`webmvc` 是同步阻塞框架,而 `webflux` 是异步非阻塞框架, +是 Spring Framework 5.0 中引入的新的响应式 web 框架。 -参考:[Spring WebFlux 入门](https://www.cnblogs.com/cjsblog/archive/2020/03/27/12580518.html)、[Spring WebFlux :: Spring Docs](https://spring.getdocs.org/en-US/spring-framework-docs/docs/spring-web-reactive/webflux/webflux.html) +参考:[Spring WebFlux 入门](https://www.cnblogs.com/cjsblog/archive/2020/03/27/12580518.html)、 +[Spring WebFlux :: Spring Docs](https://spring.getdocs.org/en-US/spring-framework-docs/docs/spring-web-reactive/webflux/webflux.html) ## 2. 一个简单的 `spring-webmvc` 项目配置 @@ -134,8 +138,10 @@ Spring bean 的加载与扩展机制有几点需要在这里简单介绍一下 这里有两个入口类: -- `servlet-class` [org.springframework.web.servlet.DispatcherServlet](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java): 指定用来处理对应 URL 请求的类 -- `listener-class` [org.springframework.web.context.ContextLoaderListener](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java): 设置事件监听器,事件监听程序在建立、修改和删除会话或 servlet 环境时得到通知 +- `servlet-class` [org.springframework.web.servlet.DispatcherServlet](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java) + : 指定用来处理对应 URL 请求的类 +- `listener-class` [org.springframework.web.context.ContextLoaderListener](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java) + : 设置事件监听器,事件监听程序在建立、修改和删除会话或 servlet 环境时得到通知 这两个类分别定义在 `spring-webmvc` 与 `spring-web` 中,下面对他们一一进行解析。 @@ -342,7 +348,7 @@ public abstract class HttpServletBean extends HttpServlet implements Environment // 初始化 @Override public final void init() throws ServletException { - // Set bean properties from init parameters. + // 把Servlet配置参数设置到bean属性中 PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties); if (!pvs.isEmpty()) { try { @@ -360,7 +366,7 @@ public abstract class HttpServletBean extends HttpServlet implements Environment } } - // Let subclasses do whatever initialization they like. + // 初始化Servlet bean initServletBean(); } @@ -389,7 +395,8 @@ public abstract class HttpServletBean extends HttpServlet implements Environment #### 3.5.1. FrameworkServlet.initServletBean -父类 `HttpServletBean` 初始化后,留下两个钩子 `initBeanWrapper, initServletBean`,`initBeanWrapper` 默认并不实现,所以来看看 `initServletBean` 钩子的实现:[FrameworkServlet.initServletBean](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java#L522) +父类 `HttpServletBean` 初始化后,留下两个钩子 `initBeanWrapper, initServletBean`,`initBeanWrapper` 默认并不实现, +所以来看看 `initServletBean` 钩子的实现:[FrameworkServlet.initServletBean](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java#L522) ```java public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware { @@ -427,7 +434,7 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic WebApplicationContext wac = null; if (this.webApplicationContext != null) { - // A context instance was injected at construction time -> use it + // 对webApplicationContext进行配置 wac = this.webApplicationContext; if (wac instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac; @@ -593,7 +600,6 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic // 扩展处理 processRequest(request, response); if (response.containsHeader("Allow")) { - // Proper OPTIONS response coming from a handler - we're done. return; } } @@ -609,7 +615,6 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic // 扩展处理 processRequest(request, response); if ("message/http".equals(response.getContentType())) { - // Proper TRACE response coming from a handler - we're done. return; } } @@ -662,7 +667,8 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic ### 3.6. DispatcherServlet -`DispatcherServlet` 主要扩展了 2 个方法:`onRefresh`、`doService`,所以来看看 [DispatcherServlet](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java) 是如何实现的 +`DispatcherServlet` 主要扩展了 2 个方法:`onRefresh`、`doService`,所以来看看 [DispatcherServlet](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java) +是如何实现的 #### 3.6.1. DispatcherServlet.onRefresh @@ -827,7 +833,8 @@ public class DispatcherServlet extends FrameworkServlet { } ``` -[DispatcherServlet.properties](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties) 文件(开发者不能自定义覆盖)如下: +[DispatcherServlet.properties](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties) +文件(开发者不能自定义覆盖)如下: ```properties # Default implementation classes for DispatcherServlet's strategy interfaces. @@ -1154,10 +1161,14 @@ public class DispatcherServlet extends FrameworkServlet { `DispatcherServlet` 这个类的解析基本上就差不多了,但还有几点没有解析: -- [FrameworkServlet(L702)](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java#L702): `ConfigurableWebApplicationContext.refresh` -- [DispatcherServlet(L514)](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java#L514): `ApplicationContext.getBean` -- [DispatcherServlet.properties](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties) 文件中定义的策略处理 -- [DispatcherServlet(L1393)](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java#L1393): `View.render` +- [FrameworkServlet(L702)](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java#L702) + : `ConfigurableWebApplicationContext.refresh` +- [DispatcherServlet(L514)](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java#L514) + : `ApplicationContext.getBean` +- [DispatcherServlet.properties](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties) + 文件中定义的策略处理 +- [DispatcherServlet(L1393)](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java#L1393) + : `View.render` 这几点,我们后面再来解析。 @@ -1170,7 +1181,8 @@ public class DispatcherServlet extends FrameworkServlet { - ContextLoaderListener ``` -[ContextLoaderListener](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java) 比较简单,只有两个监听事件方法 +[ContextLoaderListener](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java) +比较简单,只有两个监听事件方法 ```java public class ContextLoaderListener extends ContextLoader implements ServletContextListener { @@ -1190,7 +1202,8 @@ public class ContextLoaderListener extends ContextLoader implements ServletConte } ``` -[ContextLoader](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java) 的静态初始化 +[ContextLoader](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java) +的静态初始化 ```java public class ContextLoader { @@ -1207,7 +1220,8 @@ public class ContextLoader { } ``` -[ContextLoader.properties](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/resources/org/springframework/web/context/ContextLoader.properties) 文件的内容如下: +[ContextLoader.properties](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/resources/org/springframework/web/context/ContextLoader.properties) +文件的内容如下: ```properties # Default WebApplicationContext implementation class for ContextLoader. @@ -1219,7 +1233,8 @@ org.springframework.web.context.WebApplicationContext=org.springframework.web.co `ContextLoader.properties` 文件中指明使用 `XmlWebApplicationContext` 作为默认的 Web 应用上下文环境 -再来看看 [ContextLoader](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java) 的 `initWebApplicationContext` 和 `closeWebApplicationContext` +再来看看 [ContextLoader](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java) +的 `initWebApplicationContext` 和 `closeWebApplicationContext` ### 4.1. ContextLoaderListener.initWebApplicationContext @@ -1264,7 +1279,8 @@ public class ContextLoader { } ``` -`ContextLoader.configureAndRefreshWebApplicationContext` 与 `FrameworkServlet.configureAndRefreshWebApplicationContext` 的处理基本上一致。 +`ContextLoader.configureAndRefreshWebApplicationContext` 与 `FrameworkServlet.configureAndRefreshWebApplicationContext` +的处理基本上一致。 也就是说,当容器启动(如 Tomcat、Jetty、Undertow 等)时,Spring 框架会自动进行初始化。 @@ -1294,7 +1310,8 @@ public class ContextLoader { 1. 初始化 Web 应用上下文,默认使用 `XmlWebApplicationContext`(基于 XML 加载)作为应用上下文,并调用 `refresh` 方法 1. 实例化由 `globalInitializerClasses` 和 `contextInitializerClasses` 定义的类 -1. 实例化 WebMVC 必要的组件:`MultipartResolver`, `LocaleResolver`, `ThemeResolver`, `HandlerMapping`, `HandlerAdapter`, `HandlerExceptionResolver`, `RequestToViewNameTranslator`, `ViewResolver`, `FlashMapManager` +1. 实例化 WebMVC 必要的组件:`MultipartResolver`, `LocaleResolver`, `ThemeResolver`, `HandlerMapping`, + `HandlerAdapter`, `HandlerExceptionResolver`, `RequestToViewNameTranslator`, `ViewResolver`, `FlashMapManager` 每个请求都会进入到 `DispatcherServlet.service`,其主要过程是: diff --git a/spring/2.md b/spring/2.md index 74e9e66..9ae4b19 100644 --- a/spring/2.md +++ b/spring/2.md @@ -1,6 +1,6 @@ # Spring 源码解析二:SpringMVC 的上下文组件(WebApplicationContext) -上一篇分析 `DispatcherServlet` 与 `ContextLoaderListener` 这两个类,分析了应用初始化与请求处理的流程,但还有一些组件需要分析: +上一篇分析了 `DispatcherServlet` 与 `ContextLoaderListener` 这两个类,分析了应用初始化与请求处理的流程,但还有一些组件需要分析: - `ConfigurableWebApplicationContext.refresh` 刷新上下文 - `ApplicationContext.getBean` 从上下文中获取 bean @@ -20,58 +20,66 @@ org.springframework.web.context.WebApplicationContext=org.springframework.web.co `spring-web` 内部定义 5 个应用上下文类: -- [GenericWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java):`WebApplicationContext`的基础实现,但不能通过配置文件和注解加载应用配置与 bean,很少用到 -- [StaticWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/StaticWebApplicationContext.java):也是`WebApplicationContext`的基础实现,但不支持 i18n,主要用于测试,不用产品环境 -- [XmlWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/XmlWebApplicationContext.java):基于 XML 加载应用配置与 bean 的`WebApplicationContext`实现,是 SpringMVC 的默认 Context -- [AnnotationConfigWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.java):基于注解如 `@Configuration, @bean` 等加载应用配置与 bean 的`WebApplicationContext`实现,是 SpringBoot 的基础 -- [GroovyWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/GroovyWebApplicationContext.java):与`XmlWebApplicationContext`的实现差不多,但可以用 Groovy 代替 xml 做配置文件,目前用得不多 +- [GenericWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java) + :`WebApplicationContext`的基础实现,但不能通过配置文件和注解加载应用配置与 bean,很少用到 +- [StaticWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/StaticWebApplicationContext.java) + :也是`WebApplicationContext`的基础实现,但不支持 i18n,主要用于测试,不用产品环境 +- [XmlWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/XmlWebApplicationContext.java) + :基于 XML 加载应用配置与 bean 的`WebApplicationContext`实现,是 SpringMVC 的默认 Context +- [AnnotationConfigWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.java) + :基于注解如 `@Configuration, @bean` 等加载应用配置与 bean 的`WebApplicationContext`实现,是 SpringBoot 的基础 +- [GroovyWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/GroovyWebApplicationContext.java) + :与`XmlWebApplicationContext`的实现差不多,但可以用 Groovy 代替 xml 做配置文件,目前用得不多 先来看看这 5 个应用上下文类各自的继承关系 ``` -- ResourceLoader - - DefaultResourceLoader - - AbstractApplicationContext - - GenericApplicationContext - - GenericWebApplicationContext - -- ResourceLoader - - DefaultResourceLoader - - AbstractApplicationContext - - GenericApplicationContext - - StaticApplicationContext - - StaticWebApplicationContext - -- ResourceLoader - - DefaultResourceLoader - - AbstractApplicationContext - - AbstractRefreshableApplicationContext - - AbstractRefreshableConfigApplicationContext - - AbstractRefreshableWebApplicationContext - - XmlWebApplicationContext - -- ResourceLoader - - DefaultResourceLoader - - AbstractApplicationContext - - AbstractRefreshableApplicationContext - - AbstractRefreshableConfigApplicationContext - - AbstractRefreshableWebApplicationContext - - AnnotationConfigWebApplicationContext - -- ResourceLoader - - DefaultResourceLoader - - AbstractApplicationContext - - AbstractRefreshableApplicationContext - - AbstractRefreshableConfigApplicationContext - - AbstractRefreshableWebApplicationContext - - GroovyWebApplicationContext +- DefaultResourceLoader + - AbstractApplicationContext + - GenericApplicationContext + - GenericWebApplicationContext + +- DefaultResourceLoader + - AbstractApplicationContext + - GenericApplicationContext + - StaticApplicationContext + - StaticWebApplicationContext + +- DefaultResourceLoader + - AbstractApplicationContext + - AbstractRefreshableApplicationContext + - AbstractRefreshableConfigApplicationContext + - AbstractRefreshableWebApplicationContext + - XmlWebApplicationContext + +- DefaultResourceLoader + - AbstractApplicationContext + - AbstractRefreshableApplicationContext + - AbstractRefreshableConfigApplicationContext + - AbstractRefreshableWebApplicationContext + - AnnotationConfigWebApplicationContext + +- DefaultResourceLoader + - AbstractApplicationContext + - AbstractRefreshableApplicationContext + - AbstractRefreshableConfigApplicationContext + - AbstractRefreshableWebApplicationContext + - GroovyWebApplicationContext ``` -我们可以发现每个类都继承 `AbstractApplicationContext`,而 `XmlWebApplicationContext, AnnotationConfigWebApplicationContext, GroovyWebApplicationContext` 都继承 `AbstractRefreshableWebApplicationContext` +我们可以发现每个类都继承 `AbstractApplicationContext`,而 `XmlWebApplicationContext`, `AnnotationConfigWebApplicationContext`, +`GroovyWebApplicationContext` 都继承 `AbstractRefreshableWebApplicationContext` -## 1. ResourceLoader +## 1. DefaultResourceLoader -[ResourceLoader](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-core/src/main/java/org/springframework/core/io/ResourceLoader.java) +[DefaultResourceLoader](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-core/src/main/java/org/springframework/core/io/DefaultResourceLoader.java) +的主要功能是实现资源加载 + +```java +public class DefaultResourceLoader implements ResourceLoader {} +``` + +先来看看接口[ResourceLoader](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-core/src/main/java/org/springframework/core/io/ResourceLoader.java) ```java public interface ResourceLoader { @@ -83,9 +91,8 @@ public interface ResourceLoader { } ``` -## 2. DefaultResourceLoader - [DefaultResourceLoader](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-core/src/main/java/org/springframework/core/io/DefaultResourceLoader.java) +是 `ResourceLoader` 的默认实现 ```java public class DefaultResourceLoader implements ResourceLoader { @@ -128,16 +135,18 @@ public class DefaultResourceLoader implements ResourceLoader { } ``` -## 3. AbstractApplicationContext +## 2. AbstractApplicationContext [AbstractApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java) +的主要功能是通过名字、类型或注解获取 bean 实例,获取上下文的环境对象与资源、刷新上下文数据 ```java public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {} ``` -而 [ConfigurableApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java) 及其继承的接口主要定义以下的接口 +接口 [ConfigurableApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java) +及其继承的接口主要定义以下的方法 ```java public interface ConfigurableApplicationContext { @@ -165,9 +174,10 @@ public interface ConfigurableApplicationContext { } ``` -### 3.1. AbstractApplicationContext.getEnvironment +### 2.1. AbstractApplicationContext.getEnvironment [AbstractApplicationContext.getEnvironment](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java#L339) +获取环境 ```java public abstract class AbstractApplicationContext extends DefaultResourceLoader @@ -182,16 +192,17 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader protected ConfigurableEnvironment createEnvironment() { // 内置的标准环境(也可以通过setEnvironment方法自定义环境处理机制) - // 这里可以使用 `application-dev.yml, application-test.yml, application-prod.yml, ...` 来根据环境加载不同的配置的底层实现 + // 这是可以使用 `application-dev.yml, application-test.yml, application-prod.yml, ...` 来根据环境加载不同的配置的底层实现 // 是spring-boot的基本功能 return new StandardEnvironment(); } } ``` -### 3.2. AbstractApplicationContext.getBean +### 2.2. AbstractApplicationContext.getBean [AbstractApplicationContext.getBean](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java#L1157) +获取 bean ```java public abstract class AbstractApplicationContext extends DefaultResourceLoader @@ -228,9 +239,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader 因为不同的`Context`注册 bean 的方式不一样,所以`getBeanFactory`留给子类来实现 -### 3.3. AbstractApplicationContext.getBeansOfType +### 2.3. AbstractApplicationContext.getBeansOfType [AbstractApplicationContext.getBeansOfType](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java#L1303) +通过类型或注解获取 bean ```java public abstract class AbstractApplicationContext extends DefaultResourceLoader @@ -257,9 +269,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader } ``` -### 3.4. AbstractApplicationContext.refresh +### 2.4. AbstractApplicationContext.refresh [AbstractApplicationContext.refresh](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java#L550) +刷新上下文数据 ```java public abstract class AbstractApplicationContext extends DefaultResourceLoader @@ -368,9 +381,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader - 因为不同的`Context`注册 bean 的方式不一样,所以`refreshBeanFactory, postProcessBeanFactory`留给子类来实现 - `ConfigurableListableBeanFactory`如何加载、实例化 bean,后面再解析 -### 3.5. AbstractApplicationContext.prepareBeanFactory +### 2.5. AbstractApplicationContext.prepareBeanFactory [AbstractApplicationContext.prepareBeanFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java#L685) +预备 bean 工厂 ```java public abstract class AbstractApplicationContext extends DefaultResourceLoader @@ -386,7 +400,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader // 添加属性编辑器,xml、yaml 中定义的值转换成对象就是依赖这里实现的 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); - // Configure the bean factory with context callbacks. + // 添加一个BeanPostProcessor,后置处理器 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // ... 代码省略 @@ -418,9 +432,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader - `ResourceEditorRegistrar`如何注册属性编辑器、属性编辑器如何解析为对象,后面再解析 -### 3.6. AbstractApplicationContext.getResources +### 2.6. AbstractApplicationContext.getResources [AbstractApplicationContext.getResources](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java#L1415) +根据 locationPattern 获取多个资源,如通配符\* ```java public abstract class AbstractApplicationContext extends DefaultResourceLoader @@ -444,20 +459,22 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader - `PathMatchingResourcePatternResolver`如何解析、加载 locationPattern 指定的资源,后面再解析 -### 3.7. 综述 +### 2.7. 综述 总的来说,`AbstractApplicationContext` 类完成上下文环境的大部分功能,包括环境加载、bean 的加载与前置后置处理、事件派发、完成一些初始化工作等, 但扩展了几个接口给子类实现,如如何加载、注册、实例化 bean 等 -## 4. GenericApplicationContext +## 3. GenericApplicationContext [GenericApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java) +的主要功能是注册、管理 bean 的定义与别名 ```java public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {} ``` -[BeanDefinitionRegistry](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionRegistry.java) 这个接口主要定义了注册 bean 的定义及别名 +[BeanDefinitionRegistry](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionRegistry.java) +这个接口主要定义了注册 bean 的定义及别名 ```java public interface BeanDefinitionRegistry { @@ -528,9 +545,10 @@ public class GenericApplicationContext extends AbstractApplicationContext implem 最终还是落脚在 `beanFactory` 上 -## 5. GenericWebApplicationContext +## 4. GenericWebApplicationContext [GenericWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java) +的主要功能是添加了设置 bean 配置文件来源,允许通过配置的方式实例化上下文环境 ```java public class GenericWebApplicationContext extends GenericApplicationContext @@ -589,11 +607,13 @@ public class GenericWebApplicationContext extends GenericApplicationContext } ``` -`GenericWebApplicationContext` 并未实现 `ConfigurableWebApplicationContext` 的核心方法,也就不能通过文件加载配置,该类设计的目的不是在`web.xml`中进行声明式的安装,而是编程式的安装,例如使用`WebApplicationInitializers`来构建内嵌的上下文;一般很少用到 +`GenericWebApplicationContext` 并未实现 `ConfigurableWebApplicationContext` 的核心方法,也就不能通过文件加载配置, +该类设计的目的不是在`web.xml`中进行声明式的安装,而是编程式的安装,例如使用`WebApplicationInitializers`来构建内嵌的上下文;一般很少用到 -## 6. StaticWebApplicationContext +## 5. StaticWebApplicationContext -因为 [StaticApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/StaticApplicationContext.java) 实现功能比较少,放在这里一起解析 +因为 [StaticApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/StaticApplicationContext.java) +实现功能比较少,放在这里一起解析 ```java public class StaticApplicationContext extends GenericApplicationContext { @@ -610,7 +630,8 @@ public class StaticApplicationContext extends GenericApplicationContext { } ``` -[StaticWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/StaticWebApplicationContext.java) 实现功能也比较少 +[StaticWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/StaticWebApplicationContext.java) +实现功能也比较少 ```java public class StaticWebApplicationContext extends StaticApplicationContext @@ -633,11 +654,13 @@ public class StaticWebApplicationContext extends StaticApplicationContext } ``` -`StaticWebApplicationContext` 也并未实现 `ConfigurableWebApplicationContext` 的核心方法,也就不能通过文件加载配置,该类设计的目的主要用于测试,不用于产品环境 +`StaticWebApplicationContext` 也并未实现 `ConfigurableWebApplicationContext` 的核心方法,也就不能通过文件加载配置, +该类设计的目的主要用于测试,不用于产品环境 -## 7. AbstractRefreshableApplicationContext +## 6. AbstractRefreshableApplicationContext -因为 [AbstractRefreshableApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/AbstractRefreshableApplicationContext.java) +[AbstractRefreshableApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/AbstractRefreshableApplicationContext.java) +的主要功能是创建 bean 工厂,刷新上下文数据 ```java public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext { @@ -671,9 +694,10 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl } ``` -## 8. AbstractRefreshableConfigApplicationContext +## 7. AbstractRefreshableConfigApplicationContext -因为 [AbstractRefreshableConfigApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/AbstractRefreshableConfigApplicationContext.java) +[AbstractRefreshableConfigApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/support/AbstractRefreshableConfigApplicationContext.java) +的主要功能是可以通过文件加载配置 ```java public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext @@ -716,9 +740,10 @@ public abstract class AbstractRefreshableConfigApplicationContext extends Abstra - `AbstractRefreshableConfigApplicationContext` 实现了 `ConfigurableWebApplicationContext` 的核心方法,也就是可以文件加载配置 - `PropertySourcesPropertyResolver`如何是解析路径的,后面再解析 -## 9. XmlWebApplicationContext +## 8. XmlWebApplicationContext -因为 [AbstractRefreshableWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/AbstractRefreshableWebApplicationContext.java) 实现功能比较少,放在这里一起解析 +因为 [AbstractRefreshableWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/AbstractRefreshableWebApplicationContext.java) +实现功能比较少,放在这里一起解析 ```java public abstract class AbstractRefreshableWebApplicationContext extends AbstractRefreshableConfigApplicationContext @@ -732,7 +757,8 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR } ``` -因为 [XmlWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/XmlWebApplicationContext.java) 实现功能比较少,放在这里一起解析 +[XmlWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/XmlWebApplicationContext.java) +的主要功能是定义了默认的配置文件,创建一个 bean 定义的 xml 解析器,并注册 bean 定义 ```java public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext { @@ -789,16 +815,17 @@ SpringMVC 框架的默认加载机制便是使用`XmlWebApplicationContext`作 至于`XmlBeanDefinitionReader`如何是解析 bean 定义的,后面再解析 -## 10. AnnotationConfigWebApplicationContext +## 9. AnnotationConfigWebApplicationContext [AnnotationConfigWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.java) +的主要功能是可以通过注解载入配置和 bean 定义 ```java public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWebApplicationContext implements AnnotationConfigRegistry {} ``` -先来看看 [AnnotationConfigRegistry](<[AnnotationConfigWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigRegistry.java)>) +先来看看 [AnnotationConfigRegistry](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigRegistry.java) ```java public interface AnnotationConfigRegistry { @@ -897,9 +924,10 @@ public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWe 实际上,注册 bean 是由`AnnotatedBeanDefinitionReader`完成,扫描包是由`ClassPathBeanDefinitionScanner`完成,这两个类后面再解析 -## 11. GroovyWebApplicationContext +## 10. GroovyWebApplicationContext [GroovyWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/GroovyWebApplicationContext.java) +的运行机制与 `XmlWebApplicationContext` 差不多,从 `groovy` 文件加载配置与 bean 定义 ```java public class GroovyWebApplicationContext extends AbstractRefreshableWebApplicationContext implements GroovyObject { @@ -947,16 +975,22 @@ public class GroovyWebApplicationContext extends AbstractRefreshableWebApplicati } ``` -`GroovyWebApplicationContext` 的运行机制与 `XmlWebApplicationContext` 差不多,从 `groovy` 文件加载配置与 bean 定义 +## 11. 综述 -## 12. 综述 +[WebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/WebApplicationContext.java) +定义了 Web 应用初始化的基本流程,主要有 5 个实现类,常用的是:基于 Xml 加载的`XmlWebApplicationContext` +与基于注解加载的`AnnotationConfigWebApplicationContext` -[WebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/WebApplicationContext.java) 定义了 Web 应用初始化的基本流程,主要有 5 个实现类,常用的是:基于 Xml 加载的`XmlWebApplicationContext`与基于注解加载的`AnnotationConfigWebApplicationContext` +- [GenericWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java)、[StaticWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/StaticWebApplicationContext.java) + :这两者都只是`WebApplicationContext`的基础实现,都不能通过配置文件和注解加载应用配置与 bean +- [XmlWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/XmlWebApplicationContext.java) + :基于 XML 加载应用配置与 bean 的上下文环境,是 SpringMVC 的默认 Context +- [AnnotationConfigWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.java) + :基于注解如 `@Configuration, @bean` 等加载应用配置与 bean 的上下文环境,是 SpringBoot 的基础 +- [GroovyWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/GroovyWebApplicationContext.java) + :与`XmlWebApplicationContext`的实现差不多,但可以用 Groovy 代替 xml 做配置文件,但目前 Groovy 远不及 Xml 普及,用的仍然不多 -- [GenericWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/GenericWebApplicationContext.java)、[StaticWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/StaticWebApplicationContext.java):这两者都只是`WebApplicationContext`的基础实现,都不能通过配置文件和注解加载应用配置与 bean -- [XmlWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/XmlWebApplicationContext.java):基于 XML 加载应用配置与 bean 的上下文环境,是 SpringMVC 的默认 Context -- [AnnotationConfigWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.java):基于注解如 `@Configuration, @bean` 等加载应用配置与 bean 的上下文环境,是 SpringBoot 的基础 -- [GroovyWebApplicationContext](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-web/src/main/java/org/springframework/web/context/support/GroovyWebApplicationContext.java):与`XmlWebApplicationContext`的实现差不多,但可以用 Groovy 代替 xml 做配置文件,但目前 Groovy 远不及 Xml 普及,用的仍然不多 +## 12. 未完 这一节仍然有一些点留待下次解析: diff --git a/spring/3.md b/spring/3.md new file mode 100644 index 0000000..d83fbbd --- /dev/null +++ b/spring/3.md @@ -0,0 +1,1836 @@ +# Spring 源码解析三:SpringMVC 的 Bean 注册、解析、实例化机制 + +上一篇分析了上下文组件(WebApplicationContext),但留下一些点待分析: + +- `ConfigurableListableBeanFactory`如何加载、实例化 bean +- `ResourceEditorRegistrar`如何注册属性编辑器、属性编辑器如何解析为对象 +- `PathMatchingResourcePatternResolver`如何解析、加载 locationPattern 指定的资源 +- `PropertySourcesPropertyResolver`如何是解析路径的 +- `XmlBeanDefinitionReader`如何是解析 bean 定义的 +- `AnnotatedBeanDefinitionReader`是如何注册 bean 的 +- `ClassPathBeanDefinitionScanner`是如何扫描包的 + +Bean 的注册、解析、实例化主要是 [ConfigurableListableBeanFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/config/ConfigurableListableBeanFactory.java) 完成的,但`ConfigurableListableBeanFactory`只是一个接口,[DefaultListableBeanFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java) 是其默认实现 + +先来看看 `DefaultListableBeanFactory` 的集成关系 + +``` +- SimpleAliasRegistry + - DefaultSingletonBeanRegistry + - FactoryBeanRegistrySupport + - AbstractBeanFactory + - AbstractAutowireCapableBeanFactory + - DefaultListableBeanFactory +``` + +## 1. SimpleAliasRegistry + +[SimpleAliasRegistry](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-core/src/main/java/org/springframework/core/SimpleAliasRegistry.java) +简单的 bean 别名管理器 + +```java +public class SimpleAliasRegistry implements AliasRegistry {} +``` + +先来看看接口[AliasRegistry](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-core/src/main/java/org/springframework/core/AliasRegistry.java) + +```java +public interface AliasRegistry { + // 注册bean别名 + void registerAlias(String name, String alias); + + // 移除bean别名 + void removeAlias(String alias); + + // 检查是否是bean别名 + boolean isAlias(String name); + + // 获取bean别名 + String[] getAliases(String name); +} +``` + +[SimpleAliasRegistry](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-core/src/main/java/org/springframework/core/SimpleAliasRegistry.java) +是 `AliasRegistry` 的简单实现 + +```java +public class SimpleAliasRegistry implements AliasRegistry { + // 别名容器,使用ConcurrentHashMap实现 + private final Map aliasMap = new ConcurrentHashMap<>(16); + + @Override + public void registerAlias(String name, String alias) { + synchronized (this.aliasMap) { + if (alias.equals(name)) { + // 如果名字与别名相同,则删除别名 + this.aliasMap.remove(alias); + } + else { + // 载入别名 + this.aliasMap.put(alias, name); + } + } + } + + @Override + public void removeAlias(String alias) { + synchronized (this.aliasMap) { + String name = this.aliasMap.remove(alias); + } + } + + @Override + public boolean isAlias(String name) { + return this.aliasMap.containsKey(name); + } + + @Override + public String[] getAliases(String name) { + List result = new ArrayList<>(); + synchronized (this.aliasMap) { + // 根据名字反向找别名 + retrieveAliases(name, result); + } + return StringUtils.toStringArray(result); + } +} +``` + +## 2. DefaultSingletonBeanRegistry + +[DefaultSingletonBeanRegistry](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java) +默认的单例管理器 + +```java +public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {} +``` + +先来看看接口[SingletonBeanRegistry](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/config/SingletonBeanRegistry.java) + +```java +public interface SingletonBeanRegistry { + // 注册单例bean + void registerSingleton(String beanName, Object singletonObject); + + // 获取单例bean + Object getSingleton(String beanName); +} +``` + +[DefaultSingletonBeanRegistry](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java) +是 `SingletonBeanRegistry` 的默认实现 + +```java +public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { + // 单例对象Map: bean name => bean instance + private final Map singletonObjects = new ConcurrentHashMap<>(256); + + // 单例生成工厂Map: bean name => ObjectFactory + private final Map> singletonFactories = new HashMap<>(16); + + // 单例对象Map: bean name => bean instance(解决循环依赖) + private final Map earlySingletonObjects = new ConcurrentHashMap<>(16); + + // 已注册单例对象bean name集合 + private final Set registeredSingletons = new LinkedHashSet<>(256); + + // 可销毁单例对象Map: bean name => bean instance + private final Map disposableBeans = new LinkedHashMap<>(); + + // 单例对象拥有内部单例集合Map: bean name => bean instance set(比如class是一个bean,class内部的方法也是一个bean) + private final Map> containedBeanMap = new ConcurrentHashMap<>(16); + + // 单例对象的被依赖集合Map: bean name => bean instance set(其他bean依赖这个bean) + private final Map> dependentBeanMap = new ConcurrentHashMap<>(64); + + // 单例对象的依赖集合Map: bean name => bean instance set + private final Map> dependenciesForBeanMap = new ConcurrentHashMap<>(64); +} +``` + +```java +public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { + // 注入单例对象,如果已存在,则报错 + @Override + public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { + synchronized (this.singletonObjects) { + Object oldObject = this.singletonObjects.get(beanName); + if (oldObject != null) { + throw new IllegalStateException("Could not register object [" + singletonObject + + "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound"); + } + addSingleton(beanName, singletonObject); + } + } + + protected void addSingleton(String beanName, Object singletonObject) { + synchronized (this.singletonObjects) { + // 注入,临时和定义都去掉 + this.singletonObjects.put(beanName, singletonObject); + this.singletonFactories.remove(beanName); + this.earlySingletonObjects.remove(beanName); + this.registeredSingletons.add(beanName); + } + } +} +``` + +```java +public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { + // 获取单例 + public Object getSingleton(String beanName) { + return getSingleton(beanName, true); + } + + protected Object getSingleton(String beanName, boolean allowEarlyReference) { + // 先尝试从singletonObjects中获取 + Object singletonObject = this.singletonObjects.get(beanName); + // 如果没有,单例已经在创建中,还没有完成 + if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { + // 从早期集合中找(可能依赖没有完成) + singletonObject = this.earlySingletonObjects.get(beanName); + if (singletonObject == null && allowEarlyReference) { + // 如果仍然没有,锁住singletonObjects对象,从singletonFactories中创建 + synchronized (this.singletonObjects) { + singletonObject = this.singletonObjects.get(beanName); + if (singletonObject == null) { + singletonObject = this.earlySingletonObjects.get(beanName); + if (singletonObject == null) { + ObjectFactory singletonFactory = this.singletonFactories.get(beanName); + if (singletonFactory != null) { + // 从创建工厂创建单例对象 + singletonObject = singletonFactory.getObject(); + this.earlySingletonObjects.put(beanName, singletonObject); + this.singletonFactories.remove(beanName); + } + } + } + } + } + } + return singletonObject; + } + + // 获取单例,如果不存在,就用singletonFactory创建一个新的 + public Object getSingleton(String beanName, ObjectFactory singletonFactory) { + synchronized (this.singletonObjects) { + Object singletonObject = this.singletonObjects.get(beanName); + if (singletonObject == null) { + boolean newSingleton = false; + try { + // ... 代码省略 + singletonObject = singletonFactory.getObject(); + newSingleton = true; + } + catch (IllegalStateException ex) { + // ... 代码省略 + } + catch (BeanCreationException ex) { + // ... 代码省略 + } + finally { + // ... 代码省略 + } + if (newSingleton) { + addSingleton(beanName, singletonObject); + } + } + return singletonObject; + } + } +} +``` + +## 3. FactoryBeanRegistrySupport + +[FactoryBeanRegistrySupport](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java) +的主要功能是实现对 [FactoryBean](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/FactoryBean.java) +的支持 + +先来看看接口 `FactoryBean` 有哪些方法 + +```java +public interface FactoryBean { + // 获取对象实例 + T getObject() throws Exception; + + // 获取对象类型 + Class getObjectType(); +} +``` + +与 [DefaultSingletonBeanRegistry](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java) +中的对象生成接口 [ObjectFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/ObjectFactory.java) +不同的是,`FactoryBean` 多了一个 `getObjectType` 用来获取对象类型,这样就可以不用实例化也可以知道 bean 的类型,这对诸如 autowiring 自动装配对象这类功能非常有用 + +来看看 `FactoryBeanRegistrySupport` 的具体实现 + +```java +public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry { + // FactoryBeans实例缓存: FactoryBean name => object + private final Map factoryBeanObjectCache = new ConcurrentHashMap<>(16); + + // 获取factoryBean所代表的bean的类型 + protected Class getTypeForFactoryBean(FactoryBean factoryBean) { + try { + // 如果有JVM安全检查,绕过 + if (System.getSecurityManager() != null) { + return AccessController.doPrivileged( + (PrivilegedAction>) factoryBean::getObjectType, getAccessControlContext()); + } + else { + return factoryBean.getObjectType(); + } + } + catch (Throwable ex) { + // ... 代码省略 + } + } + + // 获取factoryBean所代表的bean的实例 + protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) { + // 如果是单例,并且已经创建过 + if (factory.isSingleton() && containsSingleton(beanName)) { + // 锁住父类的singletonObjects + synchronized (getSingletonMutex()) { + Object object = this.factoryBeanObjectCache.get(beanName); + if (object == null) { + // 创建实例 + object = doGetObjectFromFactoryBean(factory, beanName); + // 并发处理,有其他线程创建了,就舍弃自己创建的 + Object alreadyThere = this.factoryBeanObjectCache.get(beanName); + if (alreadyThere != null) { + object = alreadyThere; + } + else { + if (shouldPostProcess) { + // ... 代码省略 + try { + object = postProcessObjectFromFactoryBean(object, beanName); + } + catch (Throwable ex) { + // ... 代码省略 + } + finally { + // ... 代码省略 + } + } + if (containsSingleton(beanName)) { + this.factoryBeanObjectCache.put(beanName, object); + } + } + } + return object; + } + } + else { + // 如果非单例,或者单例未创建过,直接创建 + Object object = doGetObjectFromFactoryBean(factory, beanName); + if (shouldPostProcess) { + try { + // 后置处理 + object = postProcessObjectFromFactoryBean(object, beanName); + } + catch (Throwable ex) { + // ... 代码省略 + } + } + return object; + } + } + + // 创建bean + private Object doGetObjectFromFactoryBean(FactoryBean factory, String beanName) throws BeanCreationException { + Object object; + try { + // 如果有JVM安全检查,绕过 + if (System.getSecurityManager() != null) { + AccessControlContext acc = getAccessControlContext(); + try { + object = AccessController.doPrivileged((PrivilegedExceptionAction) factory::getObject, acc); + } + catch (PrivilegedActionException pae) { + // ... 代码省略 + } + } + else { + object = factory.getObject(); + } + } + catch (FactoryBeanNotInitializedException ex) { + // ... 代码省略 + } + catch (Throwable ex) { + // ... 代码省略 + } + + // 如果创建的实例是null,则返回一个NullBean实例 + if (object == null) { + if (isSingletonCurrentlyInCreation(beanName)) { + throw new BeanCurrentlyInCreationException( + beanName, "FactoryBean which is currently in creation returned null from getObject"); + } + object = new NullBean(); + } + return object; + } + + // 扩展子类后置处理 + protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException { + return object; + } +} +``` + +## 4. AbstractBeanFactory + +[AbstractBeanFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java) +是 bean 管理的核心类,主要有以下几个方法 + +- [AbstractBeanFactory.getBean](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java#L207) + 获取 bean 实例 +- [AbstractBeanFactory.getType](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java#L682) + 获取 bean 类型 + +### 4.1. AbstractBeanFactory.getBean + +```java +public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { + @Override + public Object getBean(String name) throws BeansException { + return doGetBean(name, null, null, false); + } + + @Override + public T getBean(String name, Class requiredType) throws BeansException { + return doGetBean(name, requiredType, null, false); + } + + @Override + public Object getBean(String name, Object... args) throws BeansException { + return doGetBean(name, null, args, false); + } + + public T getBean(String name, @Nullable Class requiredType, @Nullable Object... args) + throws BeansException { + return doGetBean(name, requiredType, args, false); + } + + protected T doGetBean( + String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly) + throws BeansException { + + // 获取真实的bean名称,比如别名、&开头的FactoryBean等 + String beanName = transformedBeanName(name); + Object beanInstance; + + // 先获取单例 + Object sharedInstance = getSingleton(beanName); + if (sharedInstance != null && args == null) { + // 如果是FactoryBean实例,则获取其包含的bean实例,否则就是自身 + beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); + } + else { + try { + // 如果有父bean(比如class是一个bean,class内部的方法也是一个bean),则合并父bean的定义 + RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); + + // 获取依赖 + String[] dependsOn = mbd.getDependsOn(); + if (dependsOn != null) { + for (String dep : dependsOn) { + // 记录依赖 + registerDependentBean(dep, beanName); + try { + // 保证依赖bean已经实例化 + getBean(dep); + } + catch (NoSuchBeanDefinitionException ex) { + // 如果不能实例化,抛出错误 + } + } + } + + // 单例bean + if (mbd.isSingleton()) { + // 获取单例bean,如果没有,就创建一个 + sharedInstance = getSingleton(beanName, () -> { + try { + return createBean(beanName, mbd, args); + } + catch (BeansException ex) { + // 如果不能实例化,抛出错误 + } + }); + // 如果是FactoryBean实例,则获取其包含的bean实例,否则就是自身 + beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); + } + + // 原型bean + else if (mbd.isPrototype()) { + // 每次获取都重新实例化一个新的 + Object prototypeInstance = null; + try { + prototypeInstance = createBean(beanName, mbd, args); + } + finally { + // ... 代码省略 + } + // 如果是FactoryBean实例,则获取其包含的bean实例,否则就是自身 + beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); + } + + // 否则默认每次实例化一个新的,从scope中获取beanName + else { + String scopeName = mbd.getScope(); + Scope scope = this.scopes.get(scopeName); + try { + Object scopedInstance = scope.get(beanName, () -> { + try { + return createBean(beanName, mbd, args); + } + finally { + // ... 代码省略 + } + }); + // 如果是FactoryBean实例,则获取其包含的bean实例,否则就是自身 + beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); + } + catch (IllegalStateException ex) { + // ... 代码省略 + } + } + } + catch (BeansException ex) { + // ... 代码省略 + } + finally { + // ... 代码省略 + } + } + + // 最后再根据requiredType转换bean实例类型 + return adaptBeanInstance(name, beanInstance, requiredType); + } + + // 创建实例,留给子类实现 + protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) + throws BeanCreationException; +} +``` + +### 4.2. AbstractBeanFactory.getType + +```java +public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { + @Override + public Class getType(String name) throws NoSuchBeanDefinitionException { + return getType(name, true); + } + + @Override + public Class getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException { + // 获取真实的bean名称,比如别名、&开头的FactoryBean等 + String beanName = transformedBeanName(name); + + // 先尝试获取单例 + Object beanInstance = getSingleton(beanName, false); + if (beanInstance != null && beanInstance.getClass() != NullBean.class) { + // 如果bean是FactoryBean定义的,并name不是&开头的(指包含的实际bean),则获取包含的实际bean类型 + if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) { + return getTypeForFactoryBean((FactoryBean) beanInstance); + } + // 否则获取单例本身 + else { + return beanInstance.getClass(); + } + } + + // 没有单例对象,则检查是否有定义 + BeanFactory parentBeanFactory = getParentBeanFactory(); + // 如果当前beanFactory没有定义,但有父beanFactory,则在父beanFactory里查找 + if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { + return parentBeanFactory.getType(originalBeanName(name)); + } + + // 合并父bean定义 + RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); + + // 如果是用装饰器模式定义的bean,则从装饰定义里查找 + BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); + if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) { + RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd); + Class targetClass = predictBeanType(dbd.getBeanName(), tbd); + if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) { + return targetClass; + } + } + + // 从定义中找 + Class beanClass = predictBeanType(beanName, mbd); + + // 如果bean是FactoryBean定义的 + if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) { + if (!BeanFactoryUtils.isFactoryDereference(name)) { + // name不是&开头的(指包含的实际bean),则返回包含的实际bean类型 + return getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit).resolve(); + } + else { + // 否则返回beanClass本身 + return beanClass; + } + } + // 否则返回beanClass本身 + else { + return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null); + } + } + + // 获取FactoryBean包含的实际bean类型 + protected ResolvableType getTypeForFactoryBean(String beanName, RootBeanDefinition mbd, boolean allowInit) { + // 获取定义中的factoryBeanObjectType属性 + ResolvableType result = getTypeForFactoryBeanFromAttributes(mbd); + // 如果不为空类型的话,返回 + if (result != ResolvableType.NONE) { + return result; + } + + // 如果是单例,或者非单例但可以初始化 + if (allowInit && mbd.isSingleton()) { + try { + // 获取包含这个bean的factoryBean + FactoryBean factoryBean = doGetBean(FACTORY_BEAN_PREFIX + beanName, FactoryBean.class, null, true); + Class objectType = getTypeForFactoryBean(factoryBean); + return (objectType != null ? ResolvableType.forClass(objectType) : ResolvableType.NONE); + } + catch (BeanCreationException ex) { + // ... 代码省略 + } + } + return ResolvableType.NONE; + } + + // 获取FactoryBean包含的实际bean类型 + protected Class getTypeForFactoryBean(FactoryBean factoryBean) { + try { + if (System.getSecurityManager() != null) { + // 如果有JVM安全检查,绕过 + return AccessController.doPrivileged( + (PrivilegedAction>) factoryBean::getObjectType, getAccessControlContext()); + } + else { + // 直接调用getObjectType方法 + return factoryBean.getObjectType(); + } + } + catch (Throwable ex) { + return null; + } + } + + // 根据定义查找bean类型 + protected Class predictBeanType(String beanName, RootBeanDefinition mbd, Class... typesToMatch) { + Class targetType = mbd.getTargetType(); + // 指定targetType,则返回targetType + if (targetType != null) { + return targetType; + } + // 指定了factory-method属性,如 + // + // 则返回null + if (mbd.getFactoryMethodName() != null) { + return null; + } + return resolveBeanClass(mbd, beanName, typesToMatch); + } + + // 解析bean类型 + protected Class resolveBeanClass(RootBeanDefinition mbd, String beanName, Class... typesToMatch) + throws CannotLoadBeanClassException { + + try { + // 指定beanClass且是Class,则返回beanClass + if (mbd.hasBeanClass()) { + return mbd.getBeanClass(); + } + if (System.getSecurityManager() != null) { + return AccessController.doPrivileged((PrivilegedExceptionAction>) + () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext()); + } + else { + return doResolveBeanClass(mbd, typesToMatch); + } + } + catch (PrivilegedActionException pae) { + // ... 代码省略 + } + } + + // 解析bean类型 + private Class doResolveBeanClass(RootBeanDefinition mbd, Class... typesToMatch) + throws ClassNotFoundException { + + ClassLoader beanClassLoader = getBeanClassLoader(); + ClassLoader dynamicLoader = beanClassLoader; + boolean freshResolve = false; + + // ... 代码省略 + + // 指定beanClass但是String + String className = mbd.getBeanClassName(); + if (className != null) { + // 把beanClass从String解析成对象 + Object evaluated = evaluateBeanDefinitionString(className, mbd); + if (!className.equals(evaluated)) { + // 如果是Class,直接返回 + if (evaluated instanceof Class) { + return (Class) evaluated; + } + // 如果仍是String,则用ClassLoader来加载 + else if (evaluated instanceof String) { + className = (String) evaluated; + freshResolve = true; + } + else { + // 其他对象则报错 + } + } + if (freshResolve) { + // ... 代码省略 + + return dynamicLoader.loadClass(className); + } + } + + // 如果都没有,就用哪个ClassLoader来解析 + return mbd.resolveBeanClass(beanClassLoader); + } +} +``` + +## 5. AbstractAutowireCapableBeanFactory + +[AbstractAutowireCapableBeanFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java) +的主要功能是为 bean autowiring 自动装配依赖的 bean 对象 + +```java +public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory + implements AutowireCapableBeanFactory {} +``` + +先来看看接口 [AutowireCapableBeanFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java) +的主要方法 + +```java +public interface AutowireCapableBeanFactory { + // 根据beanClass创建bean实例 + T createBean(Class beanClass) throws BeansException; + Object createBean(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; + + // 给existingBean装配依赖的其他bean实例 + void autowireBean(Object existingBean) throws BeansException; + + // 通过bean定义给existingBean装配属性 + Object configureBean(Object existingBean, String beanName) throws BeansException; + + // 根据beanClass创建并装配bean实例 + Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; +} +``` + +再来看看 [AbstractAutowireCapableBeanFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java) +是如何实现的 + +### 5.1. AbstractAutowireCapableBeanFactory.createBean + +[AbstractAutowireCapableBeanFactory.createBean](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java#L316) + +```java +public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory + implements AutowireCapableBeanFactory { + @Override + public T createBean(Class beanClass) throws BeansException { + // 创建bean定义对象,设置为原型bean + RootBeanDefinition bd = new RootBeanDefinition(beanClass); + bd.setScope(SCOPE_PROTOTYPE); + bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader()); + return (T) createBean(beanClass.getName(), bd, null); + } + + @Override + protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) + throws BeanCreationException { + RootBeanDefinition mbdToUse = mbd; + + Class resolvedClass = resolveBeanClass(mbd, beanName); + // bean对应的类是存在的,但给出的是String类型的,不是Class类型的,则需要创建bean定义对象 + if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { + mbdToUse = new RootBeanDefinition(mbd); + mbdToUse.setBeanClass(resolvedClass); + } + + // ... 代码省略 + + try { + // 做一些前置初始化,如果其中实例化了bean,则返回 + Object bean = resolveBeforeInstantiation(beanName, mbdToUse); + if (bean != null) { + return bean; + } + } + catch (Throwable ex) { + // ... 代码省略 + } + + try { + // 创建bean + Object beanInstance = doCreateBean(beanName, mbdToUse, args); + // ... 代码省略 + return beanInstance; + } + catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { + // ... 代码省略 + } + catch (Throwable ex) { + // ... 代码省略 + } + } +} +``` + +这其中有两个地方可以实例化 bean + +- [AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java#L1112) +- [AbstractAutowireCapableBeanFactory.doCreateBean](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java#L562) + +先来看看 `AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation` + +```java +public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory + implements AutowireCapableBeanFactory { + protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { + Object bean = null; + if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { + // 非自处理工具类bean,并且有BeanPostProcessor + if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { + // 获取targetType + Class targetType = determineTargetType(beanName, mbd); + if (targetType != null) { + // 初始化前置处理 + bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); + if (bean != null) { + // 初始化后置处理 + bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); + } + } + } + mbd.beforeInstantiationResolved = (bean != null); + } + return bean; + } + + // 获取targetType + protected Class determineTargetType(String beanName, RootBeanDefinition mbd, Class... typesToMatch) { + Class targetType = mbd.getTargetType(); + if (targetType == null) { + // 如果指定了factory-method属性,则调用getTypeForFactoryMethod处理 + // 否则直接解析beanClass + targetType = (mbd.getFactoryMethodName() != null ? + getTypeForFactoryMethod(beanName, mbd, typesToMatch) : + resolveBeanClass(mbd, beanName, typesToMatch)); + // ... 代码省略 + } + return targetType; + } + + // 应用InstantiationAwareBeanPostProcessors到beanClass上 + // 并调用他们的postProcessBeforeInstantiation做初始化前置处理 + protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName) { + for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { + Object result = bp.postProcessBeforeInstantiation(beanClass, beanName); + if (result != null) { + return result; + } + } + return null; + } + + // 应用BeanPostProcessors到bean实例上,并调用他们的postProcessAfterInitialization做初始化后置处理 + @Override + public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) + throws BeansException { + + Object result = existingBean; + for (BeanPostProcessor processor : getBeanPostProcessors()) { + Object current = processor.postProcessAfterInitialization(result, beanName); + if (current == null) { + return result; + } + result = current; + } + return result; + } +} +``` + +上面有一个方法没有解析,[AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java#L716) +,内容较多,但不属于这一章重点,往后有时间再解析 + +再来看看 `AbstractAutowireCapableBeanFactory.doCreateBean` + +```java +public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory + implements AutowireCapableBeanFactory { + protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) + throws BeanCreationException { + // 实例化的bean会用BeanWrapper包裹 + BeanWrapper instanceWrapper = null; + if (mbd.isSingleton()) { + // 如果是单例,先尝试从factoryBeanInstanceCache中获取 + instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); + } + if (instanceWrapper == null) { + // 没有,则创建 + instanceWrapper = createBeanInstance(beanName, mbd, args); + } + // 获取instanceWrapper包裹的bean实例 + Object bean = instanceWrapper.getWrappedInstance(); + // 获取instanceWrapper包裹的bean类型 + Class beanType = instanceWrapper.getWrappedClass(); + if (beanType != NullBean.class) { + mbd.resolvedTargetType = beanType; + } + + // ... 代码省略 + + Object exposedObject = bean; + try { + // 装载依赖的bean + populateBean(beanName, mbd, instanceWrapper); + // 对bean实例进行一些初始化操作,包括工厂回调、后置处理 + exposedObject = initializeBean(beanName, exposedObject, mbd); + } + catch (Throwable ex) { + // ... 代码省略 + } + + // ... 代码省略 + + return exposedObject; + } + + // 创建bean实例 + protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { + // 解析Class + Class beanClass = resolveBeanClass(mbd, beanName); + + Supplier instanceSupplier = mbd.getInstanceSupplier(); + if (instanceSupplier != null) { + // 如果BeanDefinition有自定义Supplier,则调用Supplier.get + return obtainFromSupplier(instanceSupplier, beanName); + } + + if (mbd.getFactoryMethodName() != null) { + // 如果指定了factory-method属性,则调用ConstructorResolver.instantiateUsingFactoryMethod处理 + return instantiateUsingFactoryMethod(beanName, mbd, args); + } + + boolean resolved = false; + boolean autowireNecessary = false; + if (args == null) { + synchronized (mbd.constructorArgumentLock) { + if (mbd.resolvedConstructorOrFactoryMethod != null) { + resolved = true; + // 需要通过构造方法装配bean + autowireNecessary = mbd.constructorArgumentsResolved; + } + } + } + if (resolved) { + if (autowireNecessary) { + // 通过构造方法装配bean + return autowireConstructor(beanName, mbd, null, null); + } + else { + // 不通过构造方法装配bean + return instantiateBean(beanName, mbd); + } + } + + // 从BeanPostProcessors中选取构造方法 + Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); + if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || + mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { + // 通过构造方法装配bean + return autowireConstructor(beanName, mbd, ctors, args); + } + + // 选择构造方法 + ctors = mbd.getPreferredConstructors(); + if (ctors != null) { + // 通过构造方法装配bean + return autowireConstructor(beanName, mbd, ctors, null); + } + + // 默认不通过构造方法装配bean + return instantiateBean(beanName, mbd); + } + + // 使用ConstructorResolver.autowireConstructor来实例化 + protected BeanWrapper autowireConstructor( + String beanName, RootBeanDefinition mbd, @Nullable Constructor[] ctors, @Nullable Object[] explicitArgs) { + + return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs); + } + + // 不通过构造方法装配bean + protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) { + try { + Object beanInstance; + if (System.getSecurityManager() != null) { + // 如果有JVM安全检查,绕过 + beanInstance = AccessController.doPrivileged( + (PrivilegedAction) () -> getInstantiationStrategy().instantiate(mbd, beanName, this), + getAccessControlContext()); + } + else { + // 默认使用CglibSubclassingInstantiationStrategy.instantiate来实例化 + beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this); + } + // 用BeanWrapper包裹bean实例 + BeanWrapper bw = new BeanWrapperImpl(beanInstance); + initBeanWrapper(bw); + return bw; + } + catch (Throwable ex) { + // ... 代码省略 + } + } + + // 对bean实例进行一些初始化操作,包括工厂回调、后置处理 + protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { + // ... 代码省略 + + Object wrappedBean = bean; + if (mbd == null || !mbd.isSynthetic()) { + // 调用BeanPostProcessors的postProcessBeforeInitialization做初始化前后置处理 + wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); + } + + try { + // 调用bean初始化后的钩子方法,如果是InitializingBean,调用afterPropertiesSet方法 + // 如果有设置initMethodName,也会调用 + invokeInitMethods(beanName, wrappedBean, mbd); + } + catch (Throwable ex) { + // ... 代码省略 + } + if (mbd == null || !mbd.isSynthetic()) { + // 调用BeanPostProcessors的postProcessAfterInitialization做初始化后后置处理 + wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); + } + + return wrappedBean; + } +} +``` + +- 这一小节留下两个点:`ConstructorResolver.autowireConstructor`和`CglibSubclassingInstantiationStrategy.instantiate`待解析 +- 另外一个方法没有解析,[ConstructorResolver.instantiateUsingFactoryMethod](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java#L394) + ,内容较多,但不属于这一章重点,往后有时间再解析 + +### 5.2. AbstractAutowireCapableBeanFactory.autowireBean + +[AbstractAutowireCapableBeanFactory.autowireBean](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java#L325) + +```java +public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory + implements AutowireCapableBeanFactory { + @Override + public void autowireBean(Object existingBean) { + // 先找出existingBean的定义对象 + RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean)); + bd.setScope(SCOPE_PROTOTYPE); + bd.allowCaching = ClassUtils.isCacheSafe(bd.getBeanClass(), getBeanClassLoader()); + // 用BeanWrapper包裹 + BeanWrapper bw = new BeanWrapperImpl(existingBean); + // 初始化 + initBeanWrapper(bw); + // 装载依赖的bean + populateBean(bd.getBeanClass().getName(), bd, bw); + } + + // 装载依赖的bean + protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { + // 获取bean的属性值集合 + PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); + + int resolvedAutowireMode = mbd.getResolvedAutowireMode(); + // 按名字或类型装配 + if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { + MutablePropertyValues newPvs = new MutablePropertyValues(pvs); + // 按名字装配 + if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { + autowireByName(beanName, mbd, bw, newPvs); + } + // 按类型装配 + if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { + autowireByType(beanName, mbd, bw, newPvs); + } + pvs = newPvs; + } + + boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); + + if (needsDepCheck) { + if (filteredPds == null) { + filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); + } + // 检查所有待装配的属性bean是否都已准备好 + checkDependencies(beanName, mbd, filteredPds, pvs); + } + + if (pvs != null) { + // 把依赖的bean装配的对象里 + applyPropertyValues(beanName, mbd, bw, pvs); + } + } + + // 按名字装配 + protected void autowireByName( + String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { + //获取需要且可以装配的属性名 + String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); + for (String propertyName : propertyNames) { + // 如果propertyName对应的bean已经实例化 + if (containsBean(propertyName)) { + Object bean = getBean(propertyName); + // 把bean载入pvs + pvs.add(propertyName, bean); + // 记录依赖 + registerDependentBean(propertyName, beanName); + } + } + } + + // 按类型装配 + protected void autowireByType( + String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { + // 自定义类型转换器,如果没有,默认使用bw + TypeConverter converter = getCustomTypeConverter(); + if (converter == null) { + converter = bw; + } + + Set autowiredBeanNames = new LinkedHashSet<>(4); + //获取需要且可以装配的属性名 + String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); + for (String propertyName : propertyNames) { + try { + // 获取属性描述器 + PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); + // Object不可装配,因为没有意义,其他Class都可装配 + if (Object.class != pd.getPropertyType()) { + // 获取可写属性 + MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); + // 确定是否有@Order注解,后置处理需要按顺序来处理 + boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); + DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); + // 解析propertyName的参数依赖 + Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); + if (autowiredArgument != null) { + // 把bean载入pvs + pvs.add(propertyName, autowiredArgument); + } + for (String autowiredBeanName : autowiredBeanNames) { + // 记录依赖 + registerDependentBean(autowiredBeanName, beanName); + } + autowiredBeanNames.clear(); + } + } + catch (BeansException ex) { + // ... 代码省略 + } + } + } + + // 把依赖的bean装配到对象里 + protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { + MutablePropertyValues mpvs = null; + // 原始值,待深拷贝(载入的对象都是深拷贝的) + List original; + + if (pvs instanceof MutablePropertyValues) { + mpvs = (MutablePropertyValues) pvs; + // ... 代码省略 + original = mpvs.getPropertyValueList(); + } + else { + original = Arrays.asList(pvs.getPropertyValues()); + } + + // 自定义类型转换器 + TypeConverter converter = getCustomTypeConverter(); + if (converter == null) { + converter = bw; + } + // bean解析器,对不同类型originalValue进行解析,如BeanDefinition、RuntimeBeanReference、ManagedList等 + BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); + + // 深拷贝的bean + List deepCopy = new ArrayList<>(original.size()); + // 对每个原始值进行处理 + for (PropertyValue pv : original) { + // ... 代码省略 + + // 属性名 + String propertyName = pv.getName(); + // 原始属性值 + Object originalValue = pv.getValue(); + + // ... 代码省略 + + // 对originalValue进行解析 + Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); + Object convertedValue = resolvedValue; + + // ... 代码省略 + + // 如果originalValue已经是解析好的PropertyValue,则直接添加 + if (resolvedValue == originalValue) { + // ... 代码省略 + + deepCopy.add(pv); + } + // ... 代码省略 + + // 不然就用PropertyValue包裹后再添加 + else { + // ... 代码省略 + + deepCopy.add(new PropertyValue(pv, convertedValue)); + } + } + // ... 代码省略 + + // 装配属性 + try { + bw.setPropertyValues(new MutablePropertyValues(deepCopy)); + } + catch (BeansException ex) { + // ... 代码省略 + } + } +} +``` + +这一小节留下 1 个点`BeanDefinitionValueResolver.resolveValueIfNecessary`待解析 + +### 5.3. AbstractAutowireCapableBeanFactory.configureBean + +[AbstractAutowireCapableBeanFactory.configureBean](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java#L336) + +```java +public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory + implements AutowireCapableBeanFactory { + @Override + public Object configureBean(Object existingBean, String beanName) throws BeansException { + // 合并父bean定义 + BeanDefinition mbd = getMergedBeanDefinition(beanName); + // 获取封装得RootBeanDefinition + RootBeanDefinition bd = null; + if (mbd instanceof RootBeanDefinition) { + RootBeanDefinition rbd = (RootBeanDefinition) mbd; + bd = (rbd.isPrototype() ? rbd : rbd.cloneBeanDefinition()); + } + if (bd == null) { + bd = new RootBeanDefinition(mbd); + } + + // 用BeanWrapper包裹bean实例 + BeanWrapper bw = new BeanWrapperImpl(existingBean); + // 初始化 + initBeanWrapper(bw); + // 装载依赖的bean + populateBean(beanName, bd, bw); + // 对bean实例进行一些初始化操作,包括工厂回调、后置处理 + return initializeBean(beanName, existingBean, bd); + } +} +``` + +### 5.4. AbstractAutowireCapableBeanFactory.autowire + +[AbstractAutowireCapableBeanFactory.autowire](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java#L371) + +```java +public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory + implements AutowireCapableBeanFactory { + @Override + public Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException { + // 创建RootBeanDefinition + RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck); + // 默认的prototype + bd.setScope(SCOPE_PROTOTYPE); + + // 通过构造方法装配bean + if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) { + return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance(); + } + // 不通过构造方法装配bean + else { + Object bean; + if (System.getSecurityManager() != null) { + // 如果有JVM安全检查,绕过 + bean = AccessController.doPrivileged( + (PrivilegedAction) () -> getInstantiationStrategy().instantiate(bd, null, this), + getAccessControlContext()); + } + else { + // 默认使用CglibSubclassingInstantiationStrategy.instantiate来实例化 + bean = getInstantiationStrategy().instantiate(bd, null, this); + } + // 装载依赖的bean + populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean)); + return bean; + } + } +} +``` + +## 6. AbstractAutowireCapableBeanFactory + +[DefaultListableBeanFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java) +的主要功能是可以获取 bean 的列表数据,比如根据类型获取 bean 列表、根据注解获取 bean 列表等 + +```java +public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory + implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {} +``` + +先来看看接口 [ConfigurableListableBeanFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/config/ConfigurableListableBeanFactory.java) +的主要方法 + +```java +public interface ConfigurableListableBeanFactory { + // 获取定义的bean名字集合 + String[] getBeanDefinitionNames(); + + // 获取指定类型的bean实例名字集合 + String[] getBeanNamesForType(ResolvableType type); + String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit); + String[] getBeanNamesForType(@Nullable Class type); + String[] getBeanNamesForType(@Nullable Class type, boolean includeNonSingletons, boolean allowEagerInit); + + // 获取指定类型的bean实例Map,如果有bean没有被创建,会抛出错误 + Map getBeansOfType(@Nullable Class type) throws BeansException; + Map getBeansOfType(@Nullable Class type, boolean includeNonSingletons, boolean allowEagerInit) + throws BeansException; + + // 在指定的bean上找指定的注解 + A findAnnotationOnBean(String beanName, Class annotationType) + throws NoSuchBeanDefinitionException; + + // 获取指定注解的bean实例名字集合 + String[] getBeanNamesForAnnotation(Class annotationType); + + // 获取指定注解的bean实例Map,如果有bean没有被创建,会抛出错误 + Map getBeansWithAnnotation(Class annotationType) throws BeansException; + + // 获取beanProvider,以使用懒加载 + ObjectProvider getBeanProvider(Class requiredType, boolean allowEagerInit); + ObjectProvider getBeanProvider(ResolvableType requiredType, boolean allowEagerInit); +} +``` + +再来看看 [DefaultListableBeanFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java) +是如何实现的 + +### 6.1. DefaultListableBeanFactory.getBeanDefinitionNames + +[DefaultListableBeanFactory.getBeanDefinitionNames](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java#L384) + +```java +public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory + implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { + // bean定义Map,name => BeanDefinition + private final Map beanDefinitionMap = new ConcurrentHashMap<>(256); + + // bean定义容器(包含定义、别名、占位符${}解析等)Map,name => BeanDefinitionHolder + private final Map mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256); + + // bean类型映射名字Map,type => name array + /** Map of singleton and non-singleton bean names, keyed by dependency type. */ + private final Map, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64); + + // 单例bean类型映射名字Map,type => name array + private final Map, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64); + + // bean定义名字集合 + private volatile List beanDefinitionNames = new ArrayList<>(256); + + // 单例bean名字集合 + private volatile Set manualSingletonNames = new LinkedHashSet<>(16); + + // 固化(不再改变)bean定义名字集合 + private volatile String[] frozenBeanDefinitionNames; + + @Override + public String[] getBeanDefinitionNames() { + // 优先使用frozenBeanDefinitionNames,其次beanDefinitionNames + String[] frozenNames = this.frozenBeanDefinitionNames; + if (frozenNames != null) { + return frozenNames.clone(); + } + else { + return StringUtils.toStringArray(this.beanDefinitionNames); + } + } +} +``` + +### 6.2. DefaultListableBeanFactory.getBeanNamesForType + +[DefaultListableBeanFactory.getBeanNamesForType](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java#L519) + +```java +public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory + implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { + @Override + public String[] getBeanNamesForType(ResolvableType type) { + return getBeanNamesForType(type, true, true); + } + + @Override + public String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) { + Class resolved = type.resolve(); + if (resolved != null && !type.hasGenerics()) { + return getBeanNamesForType(resolved, includeNonSingletons, allowEagerInit); + } + else { + return doGetBeanNamesForType(type, includeNonSingletons, allowEagerInit); + } + } + + @Override + public String[] getBeanNamesForType(@Nullable Class type) { + return getBeanNamesForType(type, true, true); + } + + @Override + public String[] getBeanNamesForType(@Nullable Class type, boolean includeNonSingletons, boolean allowEagerInit) { + if (!isConfigurationFrozen() || type == null || !allowEagerInit) { + return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit); + } + + // 先从缓存中获取,如果有缓存,直接返回 + Map, String[]> cache = + (includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType); + String[] resolvedBeanNames = cache.get(type); + if (resolvedBeanNames != null) { + return resolvedBeanNames; + } + + // 获取,并加入到缓存 + resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true); + if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) { + cache.put(type, resolvedBeanNames); + } + return resolvedBeanNames; + } +} +``` + +这里的核心是 `doGetBeanNamesForType` 方法 + +```java +public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory + implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { + private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) { + List result = new ArrayList<>(); + + // 检查所有的定义 + for (String beanName : this.beanDefinitionNames) { + // 非别名才检查 + if (!isAlias(beanName)) { + try { + // 获取合并父bean定义的RootBeanDefinition + RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); + + // ... 代码省略 + + // 判断FactoryBean + boolean isFactoryBean = isFactoryBean(beanName, mbd); + BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); + boolean matchFound = false; + + // ... 代码省略 + + // 普通bean + if (!isFactoryBean) { + if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) { + // 检查是否与类型匹配 + matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit); + } + } + else { + // FactoryBean需要特殊处理 + if (includeNonSingletons || isNonLazyDecorated || + (allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) { + // 检查是否与类型匹配 + matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit); + } + if (!matchFound) { + // 如果不匹配,尝试 &beanName 获取FactoryBean本身 + beanName = FACTORY_BEAN_PREFIX + beanName; + matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit); + } + } + if (matchFound) { + // 如果与类型匹配,则添加 + result.add(beanName); + } + } + catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) { + // ... 代码省略 + } + catch (NoSuchBeanDefinitionException ex) { + // ... 代码省略 + } + } + } + + // 检查手动注入的单例bean + for (String beanName : this.manualSingletonNames) { + try { + // FactoryBean需要特殊处理 + if (isFactoryBean(beanName)) { + // 如果与类型匹配,则添加 + if (isTypeMatch(beanName, type)) { + result.add(beanName); + continue; + } + // 如果不匹配,尝试 &beanName 获取FactoryBean本身 + beanName = FACTORY_BEAN_PREFIX + beanName; + } + // 如果与类型匹配,则添加 + if (isTypeMatch(beanName, type)) { + result.add(beanName); + } + } + catch (NoSuchBeanDefinitionException ex) { + // ... 代码省略 + } + } + + return StringUtils.toStringArray(result); + } +} +``` + +上面有一个方法没有解析,[DefaultListableBeanFactory.isTypeMatch](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java#L534) +,内容较多,但不属于这一章重点,往后有时间再解析 + +### 6.3. DefaultListableBeanFactory.getBeansOfType + +[DefaultListableBeanFactory.getBeansOfType](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java#L658) + +```java +public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory + implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { + @Override + public Map getBeansOfType(@Nullable Class type) throws BeansException { + return getBeansOfType(type, true, true); + } + + @Override + @SuppressWarnings("unchecked") + public Map getBeansOfType( + @Nullable Class type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException { + + // 先获取bean名字集合 + String[] beanNames = getBeanNamesForType(type, includeNonSingletons, allowEagerInit); + // 创建结果集合 + Map result = CollectionUtils.newLinkedHashMap(beanNames.length); + for (String beanName : beanNames) { + try { + // 获取bean实例 + Object beanInstance = getBean(beanName); + // 如果不是NullBean,则添加 + if (!(beanInstance instanceof NullBean)) { + result.put(beanName, (T) beanInstance); + } + } + catch (BeanCreationException ex) { + // ... 代码省略 + } + } + return result; + } +} +``` + +### 6.4. DefaultListableBeanFactory.findAnnotationOnBean + +[DefaultListableBeanFactory.findAnnotationOnBean](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java#L730) + +```java +public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory + implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { + @Override + public A findAnnotationOnBean(String beanName, Class annotationType) + throws NoSuchBeanDefinitionException { + + return findMergedAnnotationOnBean(beanName, annotationType) + .synthesize(MergedAnnotation::isPresent).orElse(null); + } + + private MergedAnnotation findMergedAnnotationOnBean( + String beanName, Class annotationType) { + // 先获取类型 + Class beanType = getType(beanName); + // 如果bean类型存在,直接扫描beanType(类、方法、属性),如果有,直接返回 + if (beanType != null) { + MergedAnnotation annotation = + MergedAnnotations.from(beanType, SearchStrategy.TYPE_HIERARCHY).get(annotationType); + if (annotation.isPresent()) { + return annotation; + } + } + + // 如果有定义beanName + if (containsBeanDefinition(beanName)) { + // 获取合并父bean定义的RootBeanDefinition + RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); + // 如果beanClass存在,直接扫描beanClass,如果有,直接返回 + if (bd.hasBeanClass()) { + Class beanClass = bd.getBeanClass(); + if (beanClass != beanType) { + MergedAnnotation annotation = + MergedAnnotations.from(beanClass, SearchStrategy.TYPE_HIERARCHY).get(annotationType); + if (annotation.isPresent()) { + return annotation; + } + } + } + // 如果有factory-method配置,直接扫描factoryMethod,如果有,直接返回 + Method factoryMethod = bd.getResolvedFactoryMethod(); + if (factoryMethod != null) { + MergedAnnotation annotation = + MergedAnnotations.from(factoryMethod, SearchStrategy.TYPE_HIERARCHY).get(annotationType); + if (annotation.isPresent()) { + return annotation; + } + } + } + // 如果没有,则返回MissingMergedAnnotation + return MergedAnnotation.missing(); + } +} +``` + +这一小节留下 1 个点`MergedAnnotations.from`待解析 + +### 6.5. DefaultListableBeanFactory.getBeanNamesForAnnotation + +[DefaultListableBeanFactory.getBeanNamesForAnnotation](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java#L699) + +```java +public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory + implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { + @Override + public String[] getBeanNamesForAnnotation(Class annotationType) { + List result = new ArrayList<>(); + + // 先从beanDefinitionNames中找 + for (String beanName : this.beanDefinitionNames) { + BeanDefinition bd = this.beanDefinitionMap.get(beanName); + if (bd != null && !bd.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) { + result.add(beanName); + } + } + + // 再从manualSingletonNames中找 + for (String beanName : this.manualSingletonNames) { + if (!result.contains(beanName) && findAnnotationOnBean(beanName, annotationType) != null) { + result.add(beanName); + } + } + return StringUtils.toStringArray(result); + } +} +``` + +### 6.6. DefaultListableBeanFactory.getBeansWithAnnotation + +[DefaultListableBeanFactory.getBeansWithAnnotation](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java#L716) + +```java +public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory + implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { + @Override + public Map getBeansWithAnnotation(Class annotationType) { + // 先获取有annotationType注解的bean名字集合 + String[] beanNames = getBeanNamesForAnnotation(annotationType); + // 创建结果Map + Map result = CollectionUtils.newLinkedHashMap(beanNames.length); + for (String beanName : beanNames) { + // 获取bean实例 + Object beanInstance = getBean(beanName); + // 如果不是NullBean,则添加 + if (!(beanInstance instanceof NullBean)) { + result.put(beanName, beanInstance); + } + } + return result; + } +} +``` + +### 6.7. DefaultListableBeanFactory.getBeanProvider + +[DefaultListableBeanFactory.getBeanProvider](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java#L395) + +```java +public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory + implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { + @Override + public ObjectProvider getBeanProvider(Class requiredType, boolean allowEagerInit) { + return getBeanProvider(ResolvableType.forRawClass(requiredType), allowEagerInit); + } + + @Override + public ObjectProvider getBeanProvider(ResolvableType requiredType, boolean allowEagerInit) { + return new BeanObjectProvider() { + @Override + public T getObject() throws BeansException { + // 获取requiredType的bean + T resolved = resolveBean(requiredType, null, false); + if (resolved == null) { + throw new NoSuchBeanDefinitionException(requiredType); + } + return resolved; + } + @Override + public T getObject(Object... args) throws BeansException { + // 获取requiredType的bean + T resolved = resolveBean(requiredType, args, false); + if (resolved == null) { + throw new NoSuchBeanDefinitionException(requiredType); + } + return resolved; + } + + // ... 代码省略 + + @Override + public Stream stream() { + // 获取包括祖先bean在内的,指定requiredType的bean名字集合 + return Arrays.stream(getBeanNamesForTypedStream(requiredType, allowEagerInit)) + .map(name -> (T) getBean(name)) + .filter(bean -> !(bean instanceof NullBean)); + } + + // ... 代码省略 + }; + } +} +``` + +这里的核心是 `resolveBean` 方法 + +```java +public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory + implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { + @Nullable + private T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) { + // 获取有命名的bean + NamedBeanHolder namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull); + // 如果有命名的bean,直接返回 + if (namedBean != null) { + return namedBean.getBeanInstance(); + } + + // 获取父beanFactory + BeanFactory parent = getParentBeanFactory(); + if (parent instanceof DefaultListableBeanFactory) { + // 如果父beanFactory也是DefaultListableBeanFactory,直接调用resolveBean方法 + return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull); + } + else if (parent != null) { + // 获取beanProvider,通过beanProvider获取 + ObjectProvider parentProvider = parent.getBeanProvider(requiredType); + if (args != null) { + return parentProvider.getObject(args); + } + else { + return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable()); + } + } + return null; + } + + private NamedBeanHolder resolveNamedBean( + ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException { + // 通过类型requiredType获取bean名字集合 + String[] candidateNames = getBeanNamesForType(requiredType); + + // ... 代码省略 + + if (candidateNames.length == 1) { + // 如果只有一个,直接返回 + return resolveNamedBean(candidateNames[0], requiredType, args); + } + else if (candidateNames.length > 1) { + Map candidates = CollectionUtils.newLinkedHashMap(candidateNames.length); + + // ... 代码省略 + + // 获取标记为primary的bean + String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass()); + if (candidateName == null) { + // 没有获取标记为primary的bean,则选择@Order最高的bean + candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass()); + } + if (candidateName != null) { + // 有了,获取实例 + Object beanInstance = candidates.get(candidateName); + if (beanInstance == null) { + return null; + } + // 装载 + if (beanInstance instanceof Class) { + return resolveNamedBean(candidateName, requiredType, args); + } + return new NamedBeanHolder<>(candidateName, (T) beanInstance); + } + + // ... 代码省略 + } + + return null; + } +} +``` + +## 7. 综述 + +这一节主要介绍了 Bean 的注册、解析、实例化,但 bean 的构造装载与属性值的解析,则留待后面再来解析了 + +## 8. 未完 + +这一节仍然有一些点留待下次解析: + +- `ConstructorResolver.autowireConstructor` 如何进行构造装载并实例化的 +- `CglibSubclassingInstantiationStrategy.instantiate` 如何动态实例化 bean 的 +- `BeanDefinitionValueResolver.resolveValueIfNecessary` 如何解析属性值的 +- `MergedAnnotations.from` 如何扫描注解的 + +## 后续 + +更多博客,查看 [https://github.com/senntyou/blogs](https://github.com/senntyou/blogs) + +作者:[深予之 (@senntyou)](https://github.com/senntyou) + +版权声明:自由转载-非商用-非衍生-保持署名([创意共享 3.0 许可证](https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh))