@@ -100,13 +100,14 @@ AutowireCapableBeanFactory的具体实现,它可以实现组件的自动装配
100100** 特点:**
101101
102102- DefaultListableBeanFactory 是BeanFactory的 ** 最终默认实现**
103- - DefaultListableBeanFactory会注册Bean的定义信息再创建Bean:DefaultListableBeanFactory实现
103+ - DefaultListableBeanFactory会注册Bean的定义信息再创建Bean:DefaultListableBeanFactory实现了 ** ` BeanDefinitionRegistry ` ** ,它会利用这个接口 ** 注册Bean定义信息** 。所以完整的Bean的管理是 ** 1、注册Bean的定义信息,2、完成Bean的创建和初始化动作**
104+ - DefaultListableBeanFactory不负责解析Bean定义文件
104105
106+ ### XmlBeanFactory【了解】
105107
108+ 在 SpringFramework 3.1 之后,` XmlBeanFactory ` 正式被标注为** 过时** ,代替方案是: ` DefaultListableBeanFactory + XmlBeanDefinitionReader ` 更加符合单一职责
106109
107-
108-
109- 目前的关系:
110+ ### BeanFactory体系关系图:
110111
111112``` mermaid
112113classDiagram
@@ -167,21 +168,230 @@ ListableBeanFactory --> BeanFactory
167168
168169https://c5id4ymctd.feishu.cn/wiki/EC38w0YyeiHj4PkkAvCceFbQnvB
169170
171+ ## ApplicationContext
172+
173+ 开发中推荐使用 ApplicationContext 而不是BeanFactory,因为ApplicationContext 扩展了很多功能
170174
175+ | Feature | ` BeanFactory ` | ` ApplicationContext ` |
176+ | :----------------------------------------------------------- | :------------ | :------------------- |
177+ | Bean instantiation/wiring —— Bean的实例化和属性注入 | Yes | Yes |
178+ | Integrated lifecycle management —— ** 生命周期管理** | No | Yes |
179+ | Automatic ` BeanPostProcessor ` registration —— ** Bean后置处理器的支持** | No | Yes |
180+ | Automatic ` BeanFactoryPostProcessor ` registration —— ** BeanFactory后置处理器的支持** | No | Yes |
181+ | Convenient ` MessageSource ` access (for internalization) —— ** 消息转换服务(国际化)** | No | Yes |
182+ | Built-in ` ApplicationEvent ` publication mechanism —— ** 事件发布机制(事件驱动)** | No | Yes |
171183
184+ ## 1. ApplicationContext和它的上下辈们
172185
186+ ** 特点:**
173187
188+ - ApplicationContext 是 ** 中央接口** ,最最核心,涉及一个重要概念: ** 重新加载**
174189
190+ - ApplicationContext组合多个功能接口
175191
176- ## ApplicationContext
192+ - 继承 ` ListableBeanFactory ` :具有访问应用程序组件的 Bean 工厂方法
193+
194+ - 继承 ` ResourceLoader ` 接口:以通用方式加载文件资源的能力
195+
196+ - 继承 ` ApplicationEventPublisher ` 接口:将事件发布给注册的监听器
197+
198+ - 继自 ` MessageSource ` 接口:解析消息的能力,支持国际化
199+
200+ - 从父上下文继承。在子容器中的定义将始终优先。例如,这意味着整个 Web 应用程序都可以使用单个父上下文,而每个 servlet 都有其自己的子上下文,该子上下文独立于任何其他 servlet 的子上下文。
201+
202+ > Application是层级结构的,但是这里描述的是** 父子上下文** ,** 上下文包含容器,但不仅仅是容器。容器只负责管理bean,但是上下文包含动态增强,资源加载,事件监听机制等多方面的扩展功能**
203+
204+ - ApplicationContext负责部分回调注入:ApplicationContext它集成的几个接口
205+
206+ - ` ResourceLoader ` → ` ResourceLoaderAware `
207+ - ` ApplicationEventPublisher ` → ` ApplicationEventPublisherAware `
208+ - ` MessageSource ` → ` MessageSourceAware `
209+
210+ ### ConfigurableApplicationContext【掌握】
211+
212+ 与 ** ConfigurableBeanFactory** 类似,它给ApplicationContext提供了可的功能
213+
214+ ** 特点:**
215+
216+ - ConfigurableApplicationContext 提供了可配置的功能:提供了 ` setParent ` 、` setEnvironment ` 、` addBeanFactoryPostProcessor ` 、` addApplicationListener ` 等方法,都是可以改变 ` ApplicationContext ` 本身的方法。
217+ - ConfigurableApplicationContext只希望被启动和关闭:ConfigurableApplicationContext本身扩展了一些方法,但是它一般情况下不希望让咱开发者调用,而是只调用启动(refresh)和关闭(close)方法。注意这个一般情况是在程序运行期间的业务代码中,但如果是为了定制化 ` ApplicationContext ` 或者对其进行扩展,` ConfigurableApplicationContext ` 的扩展则会成为切入的主目标。
218+
219+ ### EnvironmentCapable【熟悉】
220+
221+ ** capable** 是能力的意思,在这里解释为 ** “携带/组合”** 更为合适。
222+
223+ > ** 在 SpringFramework 中,以 Capable 结尾的接口,通常意味着可以通过这个接口的某个特定的方法(通常是 ` getXXX() ` )拿到特定的组件。**
224+
225+ ** 特点:**
226+
227+ - ApplicationContext都具有 ** EnvironmentCapable** 的功能
228+ - ` Environment ` 是 SpringFramework 中抽象出来的类似于** 运行环境** 的** 独立抽象** ,它内部存放着应用程序运行的一些配置。
229+ - 基于 SpringFramework 的工程,在运行时包含两部分:** 应用程序本身、应用程序的运行时环境** 。
230+ - ConfigurableApplicationContext可以获取ConfigurableEnvironment:可配置的ApplicationContext可以获取到可配置的Environment
231+
232+ ### MessageSource【熟悉】
233+
234+ 国际化:针对不同国家/地区,提供对应符合用户阅读的页面和数据
235+
236+ ### ApplicationEventPublisher【熟悉】
237+
238+ ApplicationEventPublisher是任务发布器。ApplicationContext需要作为观察者模式中** 广播器** 的角色
239+
240+ ### ResourcePatternResolver【熟悉】
241+
242+ 资源解析器,** 根据特定的路径去解析资源路径**
177243
244+ ** 特点:**
245+
246+ - ResourcePatternResolver是ResourceLoader的扩展:可以实现 ** Ant** 形式带有* 号的路径解析
247+ - ResourcePatternResolver的实现方式有多种
248+ - ResourcePatternResolver支持的Ant路径模式匹配,例如:例如 ` "/WEB-INF/*-context.xml" `
249+ - ResourcePatternResolver可以匹配类路径下的文件:可以匹配` classpath*: `
250+
251+ ## 2. ApplicationContext的实现类们
252+
253+ ### AbstractApplicationContext【掌握* 】
254+
255+ 这个类是 ` ApplicationContext ` ** 最最最最核心的实现类,没有之一** 。定义和实现了 ** 绝大部分应用上下文的特性和功能**
256+
257+ ** 特点:**
258+
259+ - AbstractApplicationContext只构建功能抽象,实现通用的上下文功能,让子类去实现一些具体功能
260+ - AbstractApplicationContext可以处理特殊类型的Bean:ApplicationContext能够处理一些特殊的Bean 比如 ** 后置处理器,监听器** 这些BeanFactory是不会区别对待的,但是ApplicationContext会
261+ - AbstractApplicationContext可以转化多种类型:` ApplicationContext ` 实现了国际化的接口 ` MessageSource ` 、事件广播器的接口 ` ApplicationEventMulticaster ` ,那作为容器,它也会** 把自己看成一个 Bean** ,以支持不同类型的组件注入需要。
262+ - AbstractApplicationContext 提供默认的加载资源策略:AbstractApplicationContext集成了DefaultResourceLoader。
263+
264+ > 提供生命周期的重要方法:refresh()
265+
266+ ### GenericApplicationContext【熟悉】
267+
268+ ** 注解驱动的IOC容器** ,已经是一个普通的类(非抽象类)了,它里面已经具备了 ` ApplicationContext ` 基本的所有能力了。
269+
270+ ** 重点:** GenericApplicationContext并不是集成了BeanFactory容器,而是组合了` BeanFactory `
271+
272+ ** 特点:**
273+
274+ - GenericApplicationContext借助BeanDefinitionRegistry处理特殊Bean:GenericApplicationContext因为实现了** ` BeanDefinitionRegistry ` ** 接口,可以注册bean,但是它底层还是用的 ` DefaultListableBeanFactory ` 执行 ` registerBeanDefinition ` 方法,说明它也没有对此做什么扩展。
275+ - GenericApplicationContext只能刷新一次:GenericApplicationContext只能刷新一次,BeanFactory是在` GenericApplicationContext ` 的** 构造方法中就已经初始化好** 了,一旦构造好了就不能变更过了
276+ - GenericApplicationContext的替代方案是用xml:** 注解驱动的 IOC 容器可以导入 xml 配置文件** ,不过如果大多数都是 xml 配置的话,官方建议还是直接用 ` ClassPathXmlApplicationContext ` 或者 ` FileSystemXmlApplicationContext ` 就好。
277+ - GenericApplicationContext不支持特殊Bean定义的可刷新读取
178278
279+ ### AbstractRefreshableApplicationContext【熟悉】
179280
281+ 可刷新的ApplicationContext,和GenericApplicationContext最大的区别就是,AbstractRefreshableApplicationContext可以** 被重复刷新**
180282
283+ ** 特点:**
284+
285+ - AbstractRefreshableApplicationContext支持多次刷新:每次都会创建一个新的 **** 新的内部的 ` BeanFactory ` 实例**** (也就是 ` DefaultListableBeanFactory ` )
286+ - AbstractRefreshableApplicationContext刷新的核心是加载 ` Bean的定义信息 ` :那它里面存放的 ** Bean 定义信息应该是可以被覆盖加载的** ,每次刷新时就应该重新加载 Bean 的定义信息,以及初始化 Bean 实例。
287+ - AbstractRefreshableWebApplicationContext额外扩展了Web环境的功能
288+ - 与普通的Application相比,WebApplicationContext额外扩展了与Servlet相关的部分,比如Request,ServletContext等
289+ - AbstractRefreshableApplicationContext几个重要的最终的实现类
290+ - 基于xml文件:` ClassPathXmlApplicationContext ` 和` FileSystemXmlApplicationContext `
291+ - 基于注解:` AnnotationConfigApplicationContext `
292+
293+ ### AbstractRefreshableConfigApplicationContext【了解】
294+
295+ 通篇就抽出来一句话:用于添加对指定配置位置的通用处理。由于它是基于 xml 配置的 ` ApplicationContext ` 的父类,所以肯定需要传入配置源路径,那这个配置的动作就封装在这个 ` AbstractRefreshableConfigApplicationContext ` 中了。
296+
297+ ### AbstractXmlApplicationContext【掌握】
298+
299+ AbstractXmlApplicationContext就是` ClassPathXmlApplicationContext ` 的和` FileSystemXmlApplicationContext ` 的直接父类了
300+
301+ ** 特点:**
181302
303+ - AbstractXmlApplicationContext已具备了基本的全部功能
304+ - AbstractXmlApplicationContext有loadBeanDefinitions的实现:它组合了一个 ` XmlBeanDefinitionReader `
182305
306+ ### ClassPathXmlApplicationContext【掌握】
183307
308+ 就是从classpath下加载xml配置文件的` ApplicationContext `
309+
310+ ** 特点:**
311+
312+ - ClassPathXmlApplicationContext 是一个最终的落地实现
313+ - ClassPathXmlApplicationContext使用Ant模式声明配置文件路径:比如:application-* .xml
314+ - ClassPathXmlApplicationContext解析的配置文件有先后之分:本工程resource目录下xml文件声明的bean会覆盖引入的jar包里面的xml文件里面同名的bean。
315+ - ApplicationContext可组合灵活使用:AbstractXmlApplicationContext 的本质是内部组合了` AbstractXmlApplicationContext ` ,所以除了使用ClassPathXmlApplicationContext外,我们还可以利用 ` GenericApplicationContext ` 或者子类 ` AnnotationConfigApplicationContext ` ,配合 ` XmlBeanDefinitionReader ` ,就可以做到注解驱动和 xml 通吃了。
316+
317+ ### AnnotationConfigApplicationContext【掌握】
318+
319+ AnnotationConfigApplicationContext继承了` GenericApplicationContext ` ,所以只能刷新一次。它是一个最终落地实现。
320+
321+ ** 特点:**
184322
323+ - AnnotationConfigApplicationContext是一个最终落地实现:除了@Component ,还有@Configuration 相当于xml文件
324+ - AnnotationConfigApplicationContext解析配置的顺序有先后之分:
325+
326+ # 监听器
327+
328+ spring自定义监听器的步骤
329+
330+ - 自定义事件 :实现ApplicationEvent类
331+
332+ ``` java
333+ /**
334+ * 自定义事件
335+ */
336+ public class RegisterSuccessEvent extends ApplicationEvent {
337+ RegisterSuccessEvent (Object source ) {
338+ super (source);
339+ }
340+ }
341+
342+ ```
343+
344+ - 自定义监听器:实现ApplicationListener或者使用 @EventListener 注解
345+
346+ ``` java
347+ @Component
348+ public class EmailSenderListener {
349+ @EventListener
350+ public void onRegisterSuccessEvent (RegisterSuccessEvent event ) {
351+ System . out. println(" 监听到用户注册成功,发送邮件中" );
352+ }
353+ }
354+
355+ ```
356+
357+ - 发布事件:实现ApplicationEventPublisherAware,采用才如注入的ApplicationEventPublisher进行发布
358+
359+ ``` java
360+ @Service
361+ public class RegisterService implements ApplicationEventPublisherAware {
362+
363+ ApplicationEventPublisher publisher;
364+
365+ public void register (String username ) {
366+ System . out. println(username + " 注册成功" );
367+ publisher. publishEvent(new RegisterSuccessEvent (username));
368+ }
369+
370+ @Override
371+ public void setApplicationEventPublisher (ApplicationEventPublisher applicationEventPublisher ) {
372+ this . publisher = applicationEventPublisher;
373+ }
374+ }
375+
376+ ```
377+
378+ # 模块装配
379+
380+ ## @Import
381+
382+ - 可以导入配置类
383+ - ** ` ImportSelector ` 的实现类**
384+ - ` ImportBeanDefinitionRegistrar ` 的实现类
385+ - 普通类
386+
387+ ## ImportSelector接口
388+
389+ - 可以导入普通类 (可以筛选)
390+ - 可以导入配置类(可以筛选)
391+
392+ ## ImportBeanDefinitionRegistrar接口
393+
394+ # 条件装配
185395
186396
187397
0 commit comments