, boolean)` 方法创建的。这样说,也不算准确。因为 `AbstractProxyFactory` 对象是一个子类对象,子类是通过 Dubbo 的类 SPI 加载机制来动态选择创建的。
+
+其实,Dubbo 服务消费者实例只是一个代理,通过代理封装统一的网络请求,实现 RPC 的调用过程。
+
+== Dubbo 注解集成简述
+
+使用 Dubbo 注解集成的入口是 `org.apache.dubbo.config.spring.context.annotation.EnableDubbo`,直接上代码:
+
+
+.`org.apache.dubbo.config.spring.context.annotation.EnableDubbo`
+[{java_src_attr}]
+----
+
+/**
+ * Enables Dubbo components as Spring Beans, equals
+ * {@link DubboComponentScan} and {@link EnableDubboConfig} combination.
+ *
+ * Note : {@link EnableDubbo} must base on Spring Framework 4.2 and above
+ *
+ * @see DubboComponentScan
+ * @see EnableDubboConfig
+ * @since 2.5.8
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+@EnableDubboConfig
+@DubboComponentScan
+public @interface EnableDubbo {
+
+ /**
+ * Base packages to scan for annotated @Service classes.
+ *
+ * Use {@link #scanBasePackageClasses()} for a type-safe alternative to String-based
+ * package names.
+ *
+ * @return the base packages to scan
+ * @see DubboComponentScan#basePackages()
+ */
+ @AliasFor(annotation = DubboComponentScan.class, attribute = "basePackages")
+ String[] scanBasePackages() default {};
+
+ /**
+ * Type-safe alternative to {@link #scanBasePackages()} for specifying the packages to
+ * scan for annotated @Service classes. The package of each class specified will be
+ * scanned.
+ *
+ * @return classes from the base packages to scan
+ * @see DubboComponentScan#basePackageClasses
+ */
+ @AliasFor(annotation = DubboComponentScan.class, attribute = "basePackageClasses")
+ Class>[] scanBasePackageClasses() default {};
+
+
+ /**
+ * It indicates whether {@link AbstractConfig} binding to multiple Spring Beans.
+ *
+ * @return the default value is true
+ * @see EnableDubboConfig#multiple()
+ */
+ @AliasFor(annotation = EnableDubboConfig.class, attribute = "multiple")
+ boolean multipleConfig() default true;
+
+}
+----
+
+这个注解非常重要。一共有两点需要注意。这个方法就是注解的三个属性,分别给出了三个最重要的参数:
+
+. `scanBasePackages` -- 定义了基础扫描的包。通过 `@AliasFor` 注解表明,这是定义 `@DubboComponentScan` 注解的 `basePackages` 属性。
+. `scanBasePackageClasses` -- 定义扫描的基础类。通过 `@AliasFor` 注解表明,这是定义 `@DubboComponentScan` 注解的 `basePackageClasses` 属性。
+. `multipleConfig` -- 可以将 `AbstractConfig`(上一篇文章 https://www.diguage.com/post/spring-extensions-and-dubbo-1/[Spring 扩展点实践:整合 Apache Dubbo(一)] 已经做过说明) 向 Spring 中多次注册。换句话说,你可以配置多个注册中心,配置多个监控中心等等。通过 `@AliasFor` 注解表明,这是定义 `@EnableDubboConfig` 注解的 `multiple` 属性,默认为 `true`。
+
+接下来,让我们看看非常重要的两点内容。
+
+=== `@EnableDubboConfig`
+
+`@EnableDubbo` 注解上面加了 `@EnableDubboConfig` 注解,我们来看一下它的源码:
+
+.`org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig`
+[{java_src_attr}]
+----
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+@Import(DubboConfigConfigurationRegistrar.class)
+public @interface EnableDubboConfig {
+
+ /**
+ * It indicates whether binding to multiple Spring Beans.
+ *
+ * @return the default value is true
+ * @revised 2.5.9
+ */
+ boolean multiple() default true;
+
+}
+----
+
+这里,我们看到了熟悉的 `@Import`。 `DubboConfigConfigurationRegistrar` 从名字就能看出应该是实现了 `ImportBeanDefinitionRegistrar` 接口的,打开代码,果然如此。更
+
+在 https://www.diguage.com/post/spring-extensions-overview/[Spring 扩展点概览及实践] 和 https://www.diguage.com/post/spring-extensions-and-mybatis/[Spring 扩展点实践:整合 MyBATIS] 中有针对 `@Import` 和 `ImportBeanDefinitionRegistrar` 的详细介绍。尤其是 MyBATIS 就是使用 `ImportBeanDefinitionRegistrar` 来做扩展的。不懂的,请移步。
+
+关于 `DubboConfigConfigurationRegistrar` 的功能,这里做个简要总结:
+
+. 使用 `@EnableConfigurationBeanBindings` 注解,将配置项和对一个的 Bean 类型做一个绑定。如果 `multiple` 属性为 `true`,则指出多次注册。
+. 调用 `org.apache.dubbo.config.spring.util.DubboBeanUtils#registerCommonBeans` 方法,将公共的 Bean 注册到 Spring 中。这部分内容在 https://www.diguage.com/post/spring-extensions-and-dubbo-1/#register-common-beans[Spring 扩展点实践:整合 Apache Dubbo(一):registerCommonBeans] 中已经给出了详细介绍,就不再赘述。
+
+=== `@DubboComponentScan`
+
+`@EnableDubbo` 注解上面加了 `@DubboComponentScan` 注解,直接上代码:
+
+
+.`org.apache.dubbo.config.spring.context.annotation.DubboComponentScan`
+[{java_src_attr}]
+----
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Import(DubboComponentScanRegistrar.class)
+public @interface DubboComponentScan {
+
+ /**
+ * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
+ * declarations e.g.: {@code @DubboComponentScan("org.my.pkg")} instead of
+ * {@code @DubboComponentScan(basePackages="org.my.pkg")}.
+ *
+ * @return the base packages to scan
+ */
+ String[] value() default {};
+
+ /**
+ * Base packages to scan for annotated @Service classes. {@link #value()} is an
+ * alias for (and mutually exclusive with) this attribute.
+ *
+ * Use {@link #basePackageClasses()} for a type-safe alternative to String-based
+ * package names.
+ *
+ * @return the base packages to scan
+ */
+ String[] basePackages() default {};
+
+ /**
+ * Type-safe alternative to {@link #basePackages()} for specifying the packages to
+ * scan for annotated @Service classes. The package of each class specified will be
+ * scanned.
+ *
+ * @return classes from the base packages to scan
+ */
+ Class>[] basePackageClasses() default {};
+
+}
+----
+
+又双叒叕看到了 `@Import`;又双叒叕看到了 `Registrar`,只是这次名字叫 `DubboComponentScanRegistrar`。跟上面的一样,不再赘述。
+
+这里总结一下 `DubboComponentScanRegistrar` 的功能:注册了一个类为 `ServiceAnnotationBeanPostProcessor` 的 `BeanDefinition`,将配置项的配置信息传递给这个 `BeanDefinition` 实例。 `ServiceAnnotationBeanPostProcessor` 实现了 `BeanDefinitionRegistryPostProcessor` 接口,会在 Spring 的启动过程中,通过调用 `postProcessBeanDefinitionRegistry` 方法来注册相关的 `BeanDefinition`。关于这部分内容,请移步: https://www.diguage.com/post/spring-aop-process-overview/[Spring AOP 处理流程概述]。
+
+在 Spring 启动过程中,就会调用 `ServiceAnnotationBeanPostProcessor` 的 `postProcessBeanDefinitionRegistry` 方法,在这个方法中,通过创建 `DubboClassPathBeanDefinitionScanner` (继承了 `ClassPathBeanDefinitionScanner` 类)实例,调用 `scanner.scan(packageToScan)` 来注册 `BeanDefinition`。另外,有一点需要指出的是: `ServiceAnnotationBeanPostProcessor` 目前是 `@Deprecated`,后续推荐使用 `ServiceClassPostProcessor`,而 `ServiceAnnotationBeanPostProcessor` 就是 `ServiceClassPostProcessor` 的子类。所以,目前处理逻辑都集中在了 `ServiceClassPostProcessor` 中。
+
+关于 Apache Dubbo 与 Spring 的整合原理就全部介绍完毕了。如有什么问题,欢迎留言讨论。以后有时间,写写分布式事务解决方案 Seata 的一些原理。
+
+
+// == Apache Dubbo Consumer Service Bean 的创建
+
+// . `ReferenceAnnotationBeanPostProcessor`
+
+
+// [source,java,{source_attr}]
+// ----
+// 这是啥?
+// ----
+
+// image::/images/spring-framework/dubbo-logo.jpg[{image_attr}]
+
+
+
+// . `org.apache.dubbo.config.spring.context.annotation.EnableDubbo`
+
+// . `org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig`
+// . `org.apache.dubbo.config.spring.context.annotation.DubboConfigConfigurationRegistrar`
+
+
+// . `org.apache.dubbo.config.spring.context.annotation.DubboComponentScan`
+// . `org.apache.dubbo.config.spring.context.annotation.DubboComponentScanRegistrar`
+
+
+// . `org.apache.dubbo.config.spring.beans.factory.config.DubboConfigDefaultPropertyValueBeanPostProcessor`
+// . `org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor`
+// . `org.apache.dubbo.xml.rpc.protocol.xmlrpc.XmlRpcProxyFactoryBean`
+
+// . `org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor` -- 弃用,推荐 `ServiceClassPostProcessor`。
+// . `org.apache.dubbo.config.spring.beans.factory.annotation.ServiceClassPostProcessor`
+
+// . `org.apache.dubbo.config.spring.schema.DubboBeanDefinitionParser`
+
+// . `org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigAliasPostProcessor`
+
+
+// === Seata 与 Spring 整合
+
+// . `io.seata.config.springcloud.EnableSeataSpringConfig`
+// . `io.seata.config.springcloud.SpringApplicationContextProviderRegistrar`
+// . `HttpAutoConfiguration`
+// . `RequiredAnnotationBeanPostProcessor`
+// . `SpringCacheAnnotationParser`
\ No newline at end of file
diff --git a/truman/src/docs/asciidoc/extensions-and-mybatis.adoc b/truman/src/docs/asciidoc/extensions-and-mybatis.adoc
new file mode 100644
index 000000000000..60678bbeb40b
--- /dev/null
+++ b/truman/src/docs/asciidoc/extensions-and-mybatis.adoc
@@ -0,0 +1,513 @@
+[#mybatis]
+= 整合 MyBATIS
+
+Spring 与 MyBATIS 的整合并不是 Spring 实现的,而且由 MyBATIS 项目组提供的。通过这个整合,也可以学习一下如何提供整合自己的类型框架。
+
+在上一篇文章 https://www.diguage.com/post/spring-extensions-overview/[Spring 扩展点概览及实践^] 中介绍了 Spring 内部存在的扩展点。学以致用,现在来分析一下 Spring 与 MyBATIS 的整合流程。
+
+== 示例程序
+
+为了方便分析源码,先根据官方文档 https://mybatis.org/spring/getting-started.html[mybatis-spring – MyBatis-Spring | Getting Started^] 搭建起一个简单实例。
+
+数据库方面,直接使用功能了 MySQL 示例数据库: https://dev.mysql.com/doc/employee/en/[MySQL : Employees Sample Database^],需要的话,自行下载。
+
+[#SpringMybatisTest]
+.SpringMybatisTest
+[{java_src_attr}]
+----
+include::{truman_src_dir}/mybatis/SpringMybatisTest.java[]
+----
+
+[#EmployeesMapper]
+.EmployeesMapper
+[{java_src_attr}]
+----
+include::{truman_src_dir}/mybatis/EmployeesMapper.java[]
+----
+
+[#EmployeesMapper]
+.EmployeesMapper
+[{java_src_attr}]
+----
+include::{truman_src_dir}/mybatis/MapperAop.java[]
+----
+
+[#Employees]
+.Employees
+[{java_src_attr}]
+----
+include::{truman_src_dir}/mybatis/Employees.java[]
+----
+
+整个实例代码中,只有 `@MapperScan(basePackages = "com.diguage.truman.mybatis")` 这个注解和 MyBATIS 的配置相关,我们就从这里开始吧。
+
+[#mapper-scan]
+== `@MapperScan` 处理
+
+D瓜哥在 https://www.diguage.com/post/spring-extensions-overview/#bean-definition-registry-post-processor[Spring 扩展点概览及实践:BeanDefinitionRegistryPostProcessor^] 中已经指出 `ConfigurationClassPostProcessor` 负责处理 `@Configuration` 注解。所以,可以直接去看这个类的代码。
+
+`ConfigurationClassPostProcessor` 的处理流程都是在 `processConfigBeanDefinitions(BeanDefinitionRegistry registry)` 方法中完成的。在这个方法中,可以看到如下代码:
+
+
+.`ConfigurationClassPostProcessor#processConfigBeanDefinitions`
+[{java_src_attr},highlight=68..80]
+----
+include::{context_src_dir}/context/annotation/ConfigurationClassPostProcessor.java[tag=processConfigBeanDefinitions]
+----
+
+在 `parser.parse(candidates);` 这行代码打一个断点,然后一步一步跟下去,就到了 `ConfigurationClassParser` 的 `doProcessConfigurationClass` 方法里,重点关注 `processImports` 这行:
+
+.`ConfigurationClassParser#doProcessConfigurationClass`
+[{java_src_attr},highlight=53..56]
+----
+include::{context_src_dir}/context/annotation/ConfigurationClassParser.java[tag=doProcessConfigurationClass]
+----
+
+请注意这里的 `getImports(sourceClass)`,我们看一下这个方法:
+
+[{java_src_attr}]
+----
+include::{context_src_dir}/context/annotation/ConfigurationClassParser.java[tag=getImports]
+
+include::{context_src_dir}/context/annotation/ConfigurationClassParser.java[tag=collectImports]
+----
+
+在 `String annName = annotation.getMetadata().getClassName();` 这行代码打断点,然后调试,注意观察 `annName` 变量的值,相信肯定可以看到 `org.mybatis.spring.annotation.MapperScan`,接着就可以看到,通过 `sourceClass.getAnnotationAttributes(Import.class.getName(), "value")` 解析 `@Import` 注解,把其中的 `org.mybatis.spring.annotation.MapperScannerRegistrar` 的相关信息(被封装成了 `SourceClass` 对象)加入到了 `imports` 变量中。
+
+下面看一下是如何处理 `MapperScannerRegistrar` 的。
+
+== `MapperScannerRegistrar`
+
+我们接着看 `processImports` 方法:
+
+[{java_src_attr}]
+----
+ private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
+ Collection importCandidates, Predicate exclusionFilter,
+ boolean checkForCircularImports) {
+
+ //...此处省去 N 行代码
+ else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
+ // 很明显,会进入到这个分支
+ // Candidate class is an ImportBeanDefinitionRegistrar ->
+ // delegate to it to register additional bean definitions
+ Class> candidateClass = candidate.loadClass();
+ ImportBeanDefinitionRegistrar registrar =
+ ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
+ this.environment, this.resourceLoader, this.registry);
+ // 创建一个实例,然后加入到 configClass 中
+ configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
+ //...此处省去 N 行代码
+ }
+----
+
+接着,回到 `processConfigBeanDefinitions` 方法:
+
+.`ConfigurationClassPostProcessor#processConfigBeanDefinitions`
+[{java_src_attr},highlight=79..91]
+----
+include::{context_src_dir}/context/annotation/ConfigurationClassPostProcessor.java[tag=processConfigBeanDefinitions]
+----
+
+进入 `this.reader.loadBeanDefinitions(configClasses);` 方法:
+
+.`ConfigurationClassBeanDefinitionReader#loadBeanDefinitions`
+[{java_src_attr}]
+----
+include::{context_src_dir}/context/annotation/ConfigurationClassBeanDefinitionReader.java[tag=loadBeanDefinitions]
+
+include::{context_src_dir}/context/annotation/ConfigurationClassBeanDefinitionReader.java[tag=loadBeanDefinitionsForConfigurationClass]
+
+include::{context_src_dir}/context/annotation/ConfigurationClassBeanDefinitionReader.java[tag=loadBeanDefinitionsFromImportedResources]
+
+include::{context_src_dir}/context/annotation/ConfigurationClassBeanDefinitionReader.java[tag=loadBeanDefinitionsFromRegistrars]
+----
+
+到这里就调用到了 `MapperScannerRegistrar` 的 `registerBeanDefinitions` 方法:
+
+.`MapperScannerRegistrar#registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry)`
+[{java_src_attr}]
+----
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
+ AnnotationAttributes mapperScanAttrs = AnnotationAttributes
+ .fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
+ if (mapperScanAttrs != null) {
+ registerBeanDefinitions(importingClassMetadata, mapperScanAttrs, registry,
+ generateBaseBeanName(importingClassMetadata, 0));
+ }
+ }
+
+ void registerBeanDefinitions(AnnotationMetadata annoMeta, AnnotationAttributes annoAttrs,
+ BeanDefinitionRegistry registry, String beanName) {
+
+ // 注意这行代码:
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
+ builder.addPropertyValue("processPropertyPlaceHolders", true);
+
+ Class extends Annotation> annotationClass = annoAttrs.getClass("annotationClass");
+ if (!Annotation.class.equals(annotationClass)) {
+ builder.addPropertyValue("annotationClass", annotationClass);
+ }
+
+ Class> markerInterface = annoAttrs.getClass("markerInterface");
+ if (!Class.class.equals(markerInterface)) {
+ builder.addPropertyValue("markerInterface", markerInterface);
+ }
+
+ Class extends BeanNameGenerator> generatorClass = annoAttrs.getClass("nameGenerator");
+ if (!BeanNameGenerator.class.equals(generatorClass)) {
+ builder.addPropertyValue("nameGenerator", BeanUtils.instantiateClass(generatorClass));
+ }
+
+ Class extends MapperFactoryBean> mapperFactoryBeanClass = annoAttrs.getClass("factoryBean");
+ if (!MapperFactoryBean.class.equals(mapperFactoryBeanClass)) {
+ builder.addPropertyValue("mapperFactoryBeanClass", mapperFactoryBeanClass);
+ }
+
+ String sqlSessionTemplateRef = annoAttrs.getString("sqlSessionTemplateRef");
+ if (StringUtils.hasText(sqlSessionTemplateRef)) {
+ builder.addPropertyValue("sqlSessionTemplateBeanName", annoAttrs.getString("sqlSessionTemplateRef"));
+ }
+
+ String sqlSessionFactoryRef = annoAttrs.getString("sqlSessionFactoryRef");
+ if (StringUtils.hasText(sqlSessionFactoryRef)) {
+ builder.addPropertyValue("sqlSessionFactoryBeanName", annoAttrs.getString("sqlSessionFactoryRef"));
+ }
+
+ List basePackages = new ArrayList<>();
+ basePackages.addAll(
+ Arrays.stream(annoAttrs.getStringArray("value")).filter(StringUtils::hasText).collect(Collectors.toList()));
+
+ basePackages.addAll(Arrays.stream(annoAttrs.getStringArray("basePackages")).filter(StringUtils::hasText)
+ .collect(Collectors.toList()));
+
+ basePackages.addAll(Arrays.stream(annoAttrs.getClassArray("basePackageClasses")).map(ClassUtils::getPackageName)
+ .collect(Collectors.toList()));
+
+ if (basePackages.isEmpty()) {
+ basePackages.add(getDefaultBasePackage(annoMeta));
+ }
+
+ String lazyInitialization = annoAttrs.getString("lazyInitialization");
+ if (StringUtils.hasText(lazyInitialization)) {
+ builder.addPropertyValue("lazyInitialization", lazyInitialization);
+ }
+
+ builder.addPropertyValue("basePackage", StringUtils.collectionToCommaDelimitedString(basePackages));
+
+ registry.registerBeanDefinition(beanName, builder.getBeanDefinition());
+
+ }
+----
+
+其实只干了一件事情,就是在想容器中注册了一个类为 `MapperScannerConfigurer` 的 `BeanDefinition`,在创建过程中,还把 `@MapperScan` 注解中的属性给添加到了 `BeanDefinition` 属性中。下面,来看看 `MapperScannerConfigurer` 是何方神圣。
+
+== `MapperScannerConfigurer`
+
+先看一下 `MapperScannerConfigurer` 的类型定义:
+
+[{java_src_attr}]
+----
+public class MapperScannerConfigurer
+ implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {
+----
+
+结合上一篇文章 https://www.diguage.com/post/spring-extensions-overview/#bean-definition-registry-post-processor[Spring 扩展点概览及实践:BeanDefinitionRegistryPostProcessor^] 中的介绍,可以知道 `BeanDefinitionRegistryPostProcessor` 也是 Spring 生命周期中的一环,将其注册到容器中,就可以通过对 `postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)` 来实现注册自定义 `BeanDefinition` 的功能。
+
+来看看 `postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)` 的定义:
+
+.`MapperScannerConfigurer#postProcessBeanDefinitionRegistry`
+[{java_src_attr}]
+----
+ @Override
+ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
+ if (this.processPropertyPlaceHolders) {
+ processPropertyPlaceHolders();
+ }
+
+ ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
+ scanner.setAddToConfig(this.addToConfig);
+ scanner.setAnnotationClass(this.annotationClass);
+ scanner.setMarkerInterface(this.markerInterface);
+ scanner.setSqlSessionFactory(this.sqlSessionFactory);
+ scanner.setSqlSessionTemplate(this.sqlSessionTemplate);
+ scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);
+ scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
+ scanner.setResourceLoader(this.applicationContext);
+ scanner.setBeanNameGenerator(this.nameGenerator);
+ scanner.setMapperFactoryBeanClass(this.mapperFactoryBeanClass);
+ if (StringUtils.hasText(lazyInitialization)) {
+ scanner.setLazyInitialization(Boolean.valueOf(lazyInitialization));
+ }
+ scanner.registerFilters();
+ scanner.scan(
+ StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
+ }
+----
+
+代码已经非常明确了,就是注册了一个 `ClassPathMapperScanner`,同事调用了 `scanner.scan` 方法。下面,来看一下 `ClassPathMapperScanner`。
+
+== `ClassPathMapperScanner`
+
+老规矩,先看看 `ClassPathMapperScanner` 的定义:
+
+[{java_src_attr}]
+----
+public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {
+
+ //...此处省去 N 行代码
+
+ private Class extends MapperFactoryBean> mapperFactoryBeanClass = MapperFactoryBean.class;
+
+ public ClassPathMapperScanner(BeanDefinitionRegistry registry) {
+ super(registry, false);
+ }
+----
+
+从这里可以看出,`ClassPathMapperScanner` 就是一个 `ClassPathBeanDefinitionScanner`,根据类名可以得知,扫描 `class path` 并生成 `BeanDefinition`。来看一下 `scan(String... basePackages)`
+
+.`ClassPathBeanDefinitionScanner#scan`
+[{java_src_attr}]
+----
+include::{context_src_dir}/context/annotation/ClassPathBeanDefinitionScanner.java[tag=scan]
+----
+
+这里把实际扫描工作委托给了 `doScan(basePackages)` 方法,而这个方法被 `ClassPathMapperScanner` 重写了,来看一下它的实现:
+
+.`ClassPathMapperScanner#doScan`
+[{java_src_attr}]
+----
+ /**
+ * Calls the parent search that will search and register all the candidates. Then the registered objects are post
+ * processed to set them as MapperFactoryBeans
+ */
+ @Override
+ public Set doScan(String... basePackages) {
+ Set beanDefinitions = super.doScan(basePackages);
+
+ if (beanDefinitions.isEmpty()) {
+ LOGGER.warn(() -> "No MyBatis mapper was found in '" + Arrays.toString(basePackages)
+ + "' package. Please check your configuration.");
+ } else {
+ processBeanDefinitions(beanDefinitions);
+ }
+
+ return beanDefinitions;
+ }
+----
+
+实际的扫描工作还是由父类 `super.doScan(basePackages)` 完成,只是又对扫描结果做了进一步处理: `processBeanDefinitions(beanDefinitions)`。
+
+.`ClassPathMapperScanner#processBeanDefinitions`
+[{java_src_attr}]
+----
+ private void processBeanDefinitions(Set beanDefinitions) {
+ GenericBeanDefinition definition;
+ for (BeanDefinitionHolder holder : beanDefinitions) {
+ definition = (GenericBeanDefinition) holder.getBeanDefinition();
+ String beanClassName = definition.getBeanClassName();
+ LOGGER.debug(() -> "Creating MapperFactoryBean with name '" + holder.getBeanName() + "' and '" + beanClassName
+ + "' mapperInterface");
+
+ // the mapper interface is the original class of the bean
+ // but, the actual class of the bean is MapperFactoryBean
+ // 注意这行代码
+ definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName); // issue #59
+ // 注意这行代码
+ definition.setBeanClass(this.mapperFactoryBeanClass);
+
+ definition.getPropertyValues().add("addToConfig", this.addToConfig);
+
+ boolean explicitFactoryUsed = false;
+ if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) {
+ definition.getPropertyValues().add("sqlSessionFactory",
+ new RuntimeBeanReference(this.sqlSessionFactoryBeanName));
+ explicitFactoryUsed = true;
+ } else if (this.sqlSessionFactory != null) {
+ definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory);
+ explicitFactoryUsed = true;
+ }
+
+ if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {
+ if (explicitFactoryUsed) {
+ LOGGER.warn(
+ () -> "Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
+ }
+ definition.getPropertyValues().add("sqlSessionTemplate",
+ new RuntimeBeanReference(this.sqlSessionTemplateBeanName));
+ explicitFactoryUsed = true;
+ } else if (this.sqlSessionTemplate != null) {
+ if (explicitFactoryUsed) {
+ LOGGER.warn(
+ () -> "Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
+ }
+ definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate);
+ explicitFactoryUsed = true;
+ }
+
+ if (!explicitFactoryUsed) {
+ LOGGER.debug(() -> "Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'.");
+ definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
+ }
+ definition.setLazyInit(lazyInitialization);
+ }
+ }
+----
+
+这里特别需要注意的是 `definition.setBeanClass(this.mapperFactoryBeanClass);` 这行代码。为什么把扫描出来的 `Mapper` 的 `Bean Class` 给设置成 `mapperFactoryBeanClass` 呢?通过上面的 `ClassPathMapperScanner` 类型定义可以知道,`mapperFactoryBeanClass` 就是 `MapperFactoryBean`。
+
+另外,还有一点值得思考,扫描出来的是接口,怎么生成对应的实例呢?带着这两个问题,来看一下 `MapperFactoryBean`。
+
+== `MapperFactoryBean`
+
+来看一下 `MapperFactoryBean` 的类型定义:
+
+[{java_src_attr}]
+----
+public class MapperFactoryBean extends SqlSessionDaoSupport implements FactoryBean {
+
+ private Class mapperInterface;
+
+ private boolean addToConfig = true;
+
+ public MapperFactoryBean() {
+ // intentionally empty
+ }
+
+ public MapperFactoryBean(Class mapperInterface) {
+ this.mapperInterface = mapperInterface;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void checkDaoConfig() {
+ super.checkDaoConfig();
+
+ notNull(this.mapperInterface, "Property 'mapperInterface' is required");
+
+ Configuration configuration = getSqlSession().getConfiguration();
+ if (this.addToConfig && !configuration.hasMapper(this.mapperInterface)) {
+ try {
+ configuration.addMapper(this.mapperInterface);
+ } catch (Exception e) {
+ logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", e);
+ throw new IllegalArgumentException(e);
+ } finally {
+ ErrorContext.instance().reset();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T getObject() throws Exception {
+ return getSqlSession().getMapper(this.mapperInterface);
+ }
+----
+
+可以看出 `MapperFactoryBean` 是一个 `FactoryBean`,上一篇文章 https://www.diguage.com/post/spring-extensions-overview/#factory-bean[Spring 扩展点概览及实践:FactoryBean^] 中提到,`FactoryBean` 就是专门生产 Bean 的工厂。
+
+再看构造函数 `public MapperFactoryBean(Class mapperInterface)`,结合上一个片段代码中注意的地方可以看出,从 `Class Path` 扫描出来的 `BeanDefinition`,把扫描出来的接口设置为构造函数参数 `definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);` 然后通过实例化 `FactoryBean`,然后调用 `getObject()` 就可以获得接口对应的实例对象。
+
+实例化对象的过程是由 MyBATIS 完成的,以后单独开篇来介绍,这里不再多做介绍。
+
+还有个疑问,MyBATIS 是怎么知道 Mapper 接口信息呢?这个问题就要看 `checkDaoConfig()` 方法了,单步调试代码可以知道父类 `DaoSupport#afterPropertiesSet` 调用的,在这个方法中,把 Mapper 接口信息条件到了 MyBATIS 中 `configuration.addMapper(this.mapperInterface)`。
+
+自此,MyBATIS 和 Spring 的整个流程就全部介绍完毕了。下面做个小节。
+
+== 小节
+
+本文从源码角度,深入绍了 MyBATIS 和 Spring 整合过程。整个过程中,用到了 Spring 的如下扩展点:
+
+. `@Import`
+. `MapperScannerRegistrar` - `ImportBeanDefinitionRegistrar`
+. `MapperScannerConfigurer` - `BeanDefinitionRegistryPostProcessor`
+. `ClassPathMapperScanner` - `ClassPathBeanDefinitionScanner`
+. `MapperFactoryBean` - `FactoryBean`
+. `InitializingBean`
+
+可见,和 Spring 整合并不是只靠一个扩展点就可以完成的,需要多个扩展点多方配合才能更好地完成整合过程。
+
+== 为什么在 Spring+MyBATIS 时,一级缓存失效?
+
+在原生 MyBATIS 实现中,在执行查询时,使用的 `SqlSession` 是 `DefaultSqlSession`, `DefaultSqlSession` 实例是在执行 `SqlSession session = sqlSessionFactory.openSession();` 时创建的。执行查询操作也是在 `DefaultSqlSession.selectList(String, Object, RowBounds, ResultHandler)` 中完成的。
+
+.使用 MyBAITS 原生查询
+[{java_src_attr}]
+----
+include::{truman_src_dir}/mybatis/MybatisTest.java[tag=testCacheQuery]
+
+include::{truman_src_dir}/mybatis/MybatisTest.java[tag=getDataSource]
+----
+
+Spring 的示例请看 <>、 <>、 <>。
+
+在 Spring + MyBATIS 搭配中,在执行查询时,使用的 `SqlSession` 是 `SqlSessionTemplate`(由“mybatis-spring”实现)。而 `SqlSessionTemplate` 的查询执行是委托给 `SqlSessionTemplate.sqlSessionProxy`(`SqlSession` 类型)来操作。 `SqlSessionTemplate.sqlSessionProxy` 是通过动态代理创建出来的代理实例。在代理实现内部执行时,从创建 `SqlSessionTemplate` 实例时经构造函数传入的 `SqlSessionFactory` 对象中获取 `SqlSession` 对象(创建过程与原生 MyBATIS 的构造过程相同)。最后,再去执行查询操作。
+
+在创建 `SqlSessionTemplate.sqlSessionProxy` 代理时,代理切面在执行完查询后,执行了 `closeSqlSession` 操作。正是因为执行了次操作,导致了一级缓存失效。
+
+.org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor
+[{java_src_attr},highlight=34]
+----
+ /**
+ * Proxy needed to route MyBatis method calls to the proper SqlSession got from Spring's Transaction Manager It also
+ * unwraps exceptions thrown by {@code Method#invoke(Object, Object...)} to pass a {@code PersistenceException} to the
+ * {@code PersistenceExceptionTranslator}.
+ */
+ private class SqlSessionInterceptor implements InvocationHandler {
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ SqlSession sqlSession = getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,
+ SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
+ try {
+ Object result = method.invoke(sqlSession, args);
+ if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
+ // force commit even on non-dirty sessions because some databases require
+ // a commit/rollback before calling close()
+ sqlSession.commit(true);
+ }
+ return result;
+ } catch (Throwable t) {
+ Throwable unwrapped = unwrapThrowable(t);
+ if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
+ // release the connection to avoid a deadlock if the translator is no loaded. See issue #22
+ closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
+ sqlSession = null;
+ Throwable translated = SqlSessionTemplate.this.exceptionTranslator
+ .translateExceptionIfPossible((PersistenceException) unwrapped);
+ if (translated != null) {
+ unwrapped = translated;
+ }
+ }
+ throw unwrapped;
+ } finally {
+ if (sqlSession != null) {
+ closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
+ }
+ }
+ }
+ }
+----
+
+为什么要关闭 `SqlSession`?因为 Spring 没有把 `SqlSession` 实例暴露给用户,那么用户不能控制 `SqlSession` 的关闭操作。所以,在执行完查询操作后,就马上关闭 `SqlSession` 是一个比较合理的操作。
+
+在 Spring + MyBATIS 中, `Mapper` 的信息什么时候加入到 `Configuration` 的? // TODO
+
+// == `MapperProxyFactory`
+
+// == `MapperProxy`
+
+== 参考资料
+
+. https://tech.meituan.com/2018/01/19/mybatis-cache.html[聊聊MyBatis缓存机制^] -- 文章写的很好,值得认真阅读!
+. https://www.cnblogs.com/java-chen-hao/p/11833780.html[Mybaits 源码解析 (十)- Spring-Mybatis框架使用与源码解析^]
+. https://juejin.im/post/5dbff6fae51d455c042008e6[Mybatis源码解析(一) — mybatis与Spring是如何整合的?^]
+
diff --git a/truman/src/docs/asciidoc/extensions-overview.adoc b/truman/src/docs/asciidoc/extensions-overview.adoc
new file mode 100644
index 000000000000..e4814d95f9e3
--- /dev/null
+++ b/truman/src/docs/asciidoc/extensions-overview.adoc
@@ -0,0 +1,578 @@
+= 扩展点概览及实践
+
+学习 Spring 代码,最重要的是掌握 Spring 有哪些扩展点,可以利用这些扩展点对 Spring 做什么扩展操作。说得更具体一点,如果自己开发一个框架,如何与 Spring 进行整合,如果对 Spring 的扩展点有一个比较清晰的认识,势必会事半功倍。
+
+== `@Import`
+
+先来看一下 `@Import` 注解的定义:
+
+[{java_src_attr}]
+----
+include::{context_src_dir}/context/annotation/Import.java[]
+----
+
+从声明可以看出,使用时,只需要指定 `Class` 实例即可;从方法的文档中可以看出,`Class` 实例可以分为三种:`ImportSelector`、`ImportBeanDefinitionRegistrar` 和常规组件类。示例如下:
+
+[{java_src_attr}]
+----
+@Configuration
+@Import(LogImportSelector.class)
+public static class Config {
+}
+----
+
+在 `org.springframework.context.annotation.ConfigurationClassParser#processImports` 方法中,集中了对 `@Import` 注解的处理。从代码可以非常清晰地看出,分了三种情况进行处理:
+
+. `ImportSelector`
+. `ImportBeanDefinitionRegistrar`
+. 常规组件 `Class`
+
+下面分别对其进行介绍。
+
+=== `ImportSelector`
+
+先来看一下 `ImportSelector` 接口的定义:
+
+[{java_src_attr}]
+----
+include::{context_src_dir}/context/annotation/ImportSelector.java[]
+----
+
+从接口文档中就可以看出,使用 `String[] selectImports(AnnotationMetadata importingClassMetadata)` 方法,返回所需要引入的类全限定名即可。实例如下:
+
+[{java_src_attr}]
+----
+public class LogImportSelector implements ImportSelector {
+ @Override
+ public String[] selectImports(AnnotationMetadata importingClassMetadata) {
+ return new String[]{
+ UserDao.class.getName(),
+ UserService.class.getName(),
+ ProtoService.class.getName()
+ };
+ }
+}
+----
+
+=== `ImportBeanDefinitionRegistrar`
+
+先来看一下 `ImportBeanDefinitionRegistrar` 接口的定义:
+
+[{java_src_attr}]
+----
+include::{context_src_dir}/context/annotation/ImportBeanDefinitionRegistrar.java[]
+----
+
+这里使用到了 `BeanDefinitionRegistry` 接口,来看一下这个接口的定义:
+
+[{java_src_attr}]
+----
+include::{beans_src_dir}/factory/support/BeanDefinitionRegistry.java[]
+----
+
+很明显,可以通过 `registerBeanDefinition(String beanName, BeanDefinition beanDefinition)` 方法,向容器在中注入所需要的 `BeanDefinition`,而 `BeanDefinition` 是常见的 Bean 实例的基石。示例如下:
+
+[{java_src_attr}]
+----
+public class LogImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
+ @Override
+ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
+ BeanDefinitionRegistry registry) {
+ RootBeanDefinition definition = new RootBeanDefinition(UserService.class);
+ registry.registerBeanDefinition(UserService.class.getName(), definition);
+ }
+}
+----
+
+=== 常规组件 `Class`
+
+这是最简单的情况,直接举例:
+
+[{java_src_attr}]
+----
+@Configuration
+@Import(UserService.class)
+public static class Config {
+}
+----
+
+[#bean-definition-registry-post-processor]
+== `BeanDefinitionRegistryPostProcessor`
+
+先来看一下 `BeanDefinitionRegistryPostProcessor` 的定义:
+
+[{java_src_attr}]
+----
+include::{beans_src_dir}/factory/support/BeanDefinitionRegistryPostProcessor.java[]
+----
+
+这个接口扩展了标准的 `BeanFactoryPostProcessor` 接口,允许在普通的 `BeanFactoryPostProcessor` 接口实现类执行之前注册更多的 `BeanDefinition`。特别地是,`BeanDefinitionRegistryPostProcessor` 可以注册 `BeanFactoryPostProcessor` 的 `BeanDefinition`。
+
+`postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)` 方法可以修改在 `BeanDefinitionRegistry` 接口实现类中注册的任意 `BeanDefinition`,也可以增加和删除 `BeanDefinition`。原因是这个方法执行前,所有常规的 `BeanDefinition` 已经被加载到 `BeanDefinitionRegistry` 接口实现类中,但还没有bean被实例化。
+
+实例如下:
+
+[{java_src_attr}]
+----
+public class LogBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
+ @Override
+ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
+ System.out.println(getAndIncrement()
+ + "LogBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry\n");
+ RootBeanDefinition beanDefinition = new RootBeanDefinition(LogBeanFactoryPostProcessor.class);
+ registry.registerBeanDefinition(beanDefinition.getBeanClassName(), beanDefinition);
+ }
+
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ System.out.println(getAndIncrement()
+ + "LogBeanDefinitionRegistryPostProcessor.postProcessBeanFactory\n");
+ }
+}
+----
+
+`BeanDefinitionRegistryPostProcessor` 在 Spring 内部的使用,最重要的示例就是 `ConfigurationClassPostProcessor`,这个类负责解析 `@Import` 和 `@Configuration` 等注解。感兴趣可以认真研究一下这个类的代码。
+
+
+[#bean-factory-post-processor]
+== `BeanFactoryPostProcessor`
+
+`BeanFactory` 生成后,如果想对 `BeanFactory` 进行一些处理,该怎么办呢?`BeanFactoryPostProcessor` 接口就是用来处理 `BeanFactory` 的。
+
+先来看一下接口定义:
+
+[{java_src_attr}]
+----
+include::{beans_src_dir}/factory/config/BeanFactoryPostProcessor.java[]
+----
+
+若 IoC 容器内添加了实现了 `BeanFactoryPostProcessor` 接口的实现类 Bean,那么在该容器中实例化任何其他 Bean 之前可以回调该 Bean 中的 `postPrcessorBeanFactory()` 方法来对 Bean 的配置元数据进行更改,比如设置 `init-method`,或者将 `Scope` 从 `SINGLETON` 改为 `PROTOTYPE`。示例如下:
+
+[{java_src_attr}]
+----
+public class LogBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ System.out.println(getAndIncrement()
+ + "LogBeanFactoryPostProcessor.postProcessBeanFactory\n");
+ System.out.println(Arrays.toString(beanFactory.getBeanDefinitionNames()).replaceAll(",", ",\n"));
+ BeanDefinition definition = beanFactory.getBeanDefinition(UserService.class.getName());
+ // 设置 init 方法
+ definition.setInitMethodName("init");
+ }
+}
+----
+
+在代码 `org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors` 中,集中了对 `BeanFactoryPostProcessor` 的调用。该方法把处理过程,委托给了 `org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, java.util.List)` 方法来处理。根据代码可以整理出处理流程如下:
+
+. 如果 `beanFactory` 是一个 `BeanDefinitionRegistry` 实例,则:
+.. 首先处理参数传过来的 `List beanFactoryPostProcessors` 对象
+... 如果 `postProcessor` 是 `BeanDefinitionRegistryPostProcessor` 实现类,则直接调用 `postProcessBeanDefinitionRegistry`,然后加入到 `List registryProcessors` 列表中;
+... 如果不是,则加入到 `List regularPostProcessors` 列表中;
+.. 从 `BeanFactory` 中通过 `beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)` 方法获取 `BeanDefinitionRegistryPostProcessor` 名称列表。筛选出实现了 `PriorityOrdered` 接口的实例,然后排序再逐一调用 `postProcessBeanDefinitionRegistry` 方法。最后,加入到 `List registryProcessors` 列表中。
+.. 从 `BeanFactory` 中通过 `beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)` 方法获取 `BeanDefinitionRegistryPostProcessor` 名称列表。筛选出实现了 `Ordered` 接口的实例,然后排序再逐一调用 `postProcessBeanDefinitionRegistry` 方法。最后,加入到 `List registryProcessors` 列表中。(注意:上一步已经调用过的则不再重复调用。)
+.. 从 `BeanFactory` 中通过 `beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)` 方法获取 `BeanDefinitionRegistryPostProcessor` 名称列表。剔除掉前两步调用过的类,排序再逐一调用 `postProcessBeanDefinitionRegistry` 方法。最后,加入到 `List registryProcessors` 列表中。要强调的一点是:这里是通过一个循环来反复执行这一步,D瓜哥认为是在调用 `postProcessBeanDefinitionRegistry` 方法中,有会参数新注册的 `BeanDefinitionRegistryPostProcessor`,所以需要反复调用。大家如果有不同见解,也欢迎留言讨论。
+.. 调用 `BeanDefinitionRegistryPostProcessor` 对象的 `postProcessBeanFactory` 方法;
+.. 调用 `BeanFactoryPostProcessor` 对象的 `postProcessBeanFactory` 方法;
+. 如果 `beanFactory` 不是 `BeanDefinitionRegistry` 实例,则直接调用 `BeanFactoryPostProcessor` 对象的 `postProcessBeanFactory` 方法;
+. 从 `BeanFactory` 中通过 `beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false)` 方法获取 `BeanFactoryPostProcessor` 名称列表。将其分为:
+.. 实现 `PriorityOrdered` 接口的实例
+.. 实现 `Ordered` 接口的实例
+.. 未排序的实例
++
+按照这个顺序,排除已经处理过的实例,再分类,然后排序再跟着这个顺序依次逐一调用 `BeanFactoryPostProcessor` 对象的 `postProcessBeanFactory` 方法;
++
+. 最后,向 `BeanFactory` 注册 `ApplicationListenerDetector` 实例。
+
+
+== `InstantiationAwareBeanPostProcessor`
+
+注意区分 *`Instantiation`* 和 *`Initialization`*。
+
+* *`Instantiation`* -- 实例化,在实例化之前还没有生成对象。
+* *`Initialization`* -- 初始化,对象已经生成,需要对其做进一步的处理,比如赋值等。
+
+[#factory-bean]
+== `FactoryBean`
+
+在对象生成上,有时也许需要做些特殊处理。比如,创建对象过程比较繁琐,希望可以通过实现 `FactoryBean` 来封装初始化过程。
+
+在 Spring 官方文档 https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-extension-factorybean[Core Technologies: Customizing Instantiation Logic with a `FactoryBean`^] 也有进一步的说明。
+
+目前,Spring 源码中,`FactoryBean` 的实现类就有五十多个,随便举几个栗子🌰:
+
+* `org.springframework.http.converter.json.GsonFactoryBean`
+* `org.springframework.cache.jcache.JCacheManagerFactoryBean`
+* `org.springframework.aop.framework.ProxyFactoryBean`
+
+示例如下:
+
+[{java_src_attr}]
+----
+package com.diguage.truman.context;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.annotation.*;
+
+import java.util.Arrays;
+
+/**
+ * FactoryBean 测试
+ *
+ * @author D瓜哥 · https://www.diguage.com
+ * @since 2020-05-26 16:34
+ */
+public class FactoryBeanTest {
+ @Test
+ public void test() {
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+ context.register(Config.class);
+ context.refresh();
+
+ UserService userService = context.getBean(UserService.class);
+ System.out.println(userService.getById(119L));
+
+ System.out.println("-↓----");
+ System.out.println("&userServiceFactoryBean = " // <1>
+ + context.getBean("&userServiceFactoryBean"));
+ System.out.println(" userServiceFactoryBean = " // <2>
+ + context.getBean("userServiceFactoryBean"));
+ System.out.println("-↑----");
+
+ UserServiceFactoryBean factoryBean = context.getBean(UserServiceFactoryBean.class);
+ System.out.println(factoryBean);
+ System.out.println(Arrays.toString(context.getBeanDefinitionNames())
+ .replaceAll(",", ",\n"));
+ }
+
+ @Configuration
+ public static class Config {
+ @Bean
+ public UserServiceFactoryBean userServiceFactoryBean() {
+ return new UserServiceFactoryBean();
+ }
+ }
+
+
+ public static class UserService {
+ public String getById(Long id) {
+ return "Name-" + id;
+ }
+ }
+
+ public static class UserServiceFactoryBean implements FactoryBean {
+ @Override
+ public UserService getObject() throws Exception {
+ return new UserService();
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return UserService.class;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return false;
+ }
+ }
+}
+----
+<1> 通过 Bean 名称 `&userServiceFactoryBean` 获得的 Bean 是 `UserServiceFactoryBean` 对象;
+<2> 通过 Bean 名称 `userServiceFactoryBean` 获得的 Bean 是 `UserService` 对象;
+
+有一点需要强调一下:`&` 符号的使用需要注意。上面的代码和相应注释给出了说明。
+
+
+== `ObjectFactory`
+
+D瓜哥个人认为 `FactoryBean` 和 `ObjectFactory` 功能有些重叠,都是为了创建对象而设计的。
+
+通过 `ObjectFactory` 的文档,Spring 给出了官方解释:
+
+****
+这个接口通常用于封装一个通用的工厂,它在每次调用时返回某个目标对象的新实例(原型)。
+
+这个接口类似于 `FactoryBean`,但后者的实现通常是作为 `BeanFactory` 中的 SPI 实例来定义,而这个类的实现通常是作为 API 馈送给其他 Bean(通过注入)。因此,getObject()方法有不同的异常处理行为。
+****
+
+Spring 在解决循环依赖时和在创建 Bean 时,都使用到接口。它似乎可以脱离 Spring 单独使用。
+
+== `ObjectProvider`
+
+`ObjectProvider` 继承了 `ObjectFactory` 接口,它是后者的一个变体,提供了更加丰富的操作 `T getIfAvailable()`,T getIfUnique() 等。在 Spring 5.1 以后,有继承了 `Iterable` 接口,方法用于循环或者 `forEach` 方法。在 `org.springframework.beans.factory.support.DefaultListableBeanFactory` 中有使用示例。
+
+== `BeanPostProcessor`
+
+`BeanPostProcessor` 是 Spring 中最最重要的扩展点。Spring 内部大量的功能 IoC 和 AOP 也都是通过 `BeanPostProcessor` 来实现的。先来看一下接口定义:
+
+[{java_src_attr}]
+----
+include::{beans_src_dir}/factory/config/BeanPostProcessor.java[]
+----
+
+具体到实际应用上,Spring 内置了大量的应用:
+
+. `ApplicationContextAwareProcessor` -- `Aware` 接口的处理。
+. `InitDestroyAnnotationBeanPostProcessor` -- `init-method` 和 `destroy-method` 方法的调用。
+. `InstantiationAwareBeanPostProcessor`
+. `CommonAnnotationBeanPostProcessor` -- 常用注解 `@Resource`、`@PostConstruct` 和 `@PreDestroy` 的解析。
+. `AutowiredAnnotationBeanPostProcessor` -- 常用注解 `@Autowired`、`@Value` 和 `@Inject` 的解析。
+. `BeanValidationPostProcessor` -- 字段校验。
+. `AbstractAutoProxyCreator` -- 生成代理。
+
+少废话,直接上代码:
+
+[{java_src_attr}]
+----
+public class LogBeanPostProcessor implements BeanPostProcessor {
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ if (bean instanceof UserService) {
+ System.out.println(getAndIncrement()
+ + "LogBeanPostProcessor.postProcessBeforeInitialization");
+ System.out.println(bean);
+ System.out.println();
+ }
+ return bean;
+ }
+
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ if (bean instanceof UserService) {
+ System.out.println(getAndIncrement()
+ + "LogBeanPostProcessor.postProcessAfterInitialization");
+ System.out.println(bean);
+ System.out.println();
+ }
+ return bean;
+ }
+}
+
+// 将其注册到 BeanFactory 上
+beanFactory.addBeanPostProcessor(new LogBeanPostProcessor());
+----
+
+在 `org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition)` 方法中,通过 `applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)` 和 `applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)` 来分别调用 `postProcessBeforeInitialization` 和 `postProcessAfterInitialization` 方法。
+
+== 各种 Aware
+
+有时,自己开发的代码可能需要 `ApplicationContext` 或者 `BeanFactory` 等实例。则可以通过实现相应的 `Aware` 接口来获得对应的实例。目前有如下这些 `Aware` 接口:
+
+. `ApplicationContextAware`
+. `ApplicationEventPublisherAware`
+. `BeanClassLoaderAware`
+. `BeanFactoryAware`
+. `BeanNameAware`
+. `BootstrapContextAware`
+. `EmbeddedValueResolverAware`
+. `EnvironmentAware`
+. `ImportAware`
+. `LoadTimeWeaverAware`
+. `MessageSourceAware`
+. `NotificationPublisherAware`
+. `ResourceLoaderAware`
+. `SchedulerContextAware`
+. `ServletConfigAware`
+. `ServletContextAware`
+
+在代码 `org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces` 中,集中处理了 `EnvironmentAware`、`EmbeddedValueResolverAware`、`ResourceLoaderAware`、`ApplicationEventPublisherAware`、`MessageSourceAware` 和 `ApplicationContextAware` 等六种 `Aware` 注入。值得一提的是,通过类的定义可以得知,`ApplicationContextAwareProcessor` 是一个 `BeanPostProcessor` 实现类,那么 `BeanPostProcessor` 的处理机制也通过适用于该类。
+
+=== `ApplicationContextAware`
+
+如果某个 Bean 实现了 `ApplicationContextAware` 接口,那么 Spring 将会将该 Bean 所在的上下文环境 `ApplicationContext` 传递给 `setApplicationContext()` 方法,在 Bean 类中新增一个 `ApplicationContext` 字段用来保存 `ApplicationContext` 的值,并实现 `setApplicationContext()` 方法。
+
+[{java_src_attr}]
+----
+@Service
+public static class UserService implements InitializingBean, ApplicationContextAware {
+ @Resource
+ UserDao userDao;
+
+ ApplicationContext applicationContext;
+
+ public UserService() {
+ System.out.println(getAndIncrement()
+ + "UserService()\n");
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ System.out.println(getAndIncrement()
+ + "UserService.afterPropertiesSet\n");
+ }
+
+ public void init() {
+ System.out.println(getAndIncrement()
+ + "UserService.init\n");
+ }
+
+ String getById(Long id) {
+ return userDao.getById(id);
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ System.out.println(getAndIncrement()
+ + "UserService.setApplicationContext\n");
+ this.applicationContext = applicationContext;
+ }
+}
+----
+
+=== `BeanClassLoaderAware`
+
+如果某个 Bean 实现了 `BeanClassLoaderAware` 接口,那么 Spring 将会将创建 Bean 的 `ClassLoader` 传递给 `setBeanClassLoader()` 方法,在 Bean 类中新增了一个 `classLoader` 字段用来保存 `ClassLoader` 的值,并实现 `setBeanClassLoader()` 方法。
+
+=== `BeanFactoryAware`
+
+如果某个 Bean 实现了 `BeanFactoryAware` 接口,那么 Spring 将会将创建 Bean 的 `BeanFactory` 传递给 `setBeanFactory()` 方法,在 Bean 类中新增了一个 `beanFactory` 字段用来保存 `BeanFactory` 的值,并实现 `setBeanFactory()` 方法。
+
+=== `BeanNameAware`
+
+如果某个 Bean 实现了 `BeanNameAware` 接口,那么 Spring 将会将 Bean 实例的ID传递给 `setBeanName()` 方法,在 Bean 类中新增一个 `beanName` 字段,并实现 `setBeanName()` 方法。
+
+=== `ServletContextAware`
+
+这个接口只能在 Web 项目中使用。
+
+如果某个 Bean 实现了 `ServletContextAware` 接口,那么 Spring 将会将 `ServletContext` 传递给 `setServletContext()` 方法,在 Bean 类中新增一个字段,并实现 `setServletContext()` 方法。
+
+[#InitializingBean-vs-init-method]
+== `InitializingBean` 与 `init-method`
+
+设置 `init-method` 方法和实现 `InitializingBean` 方法达到的效果是一样的。在代码 `org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods` 中可以看到很详细的处理流程:
+
+. 判断 Bean 是否是 `InitializingBean` 实例,如果是,则做类型转换,然后再调用其 `afterPropertiesSet()` 方法;
+. 获取 `AbstractBeanDefinition#initMethodName` 属性,然后判断是否合法(①长度大于零,②和第一步条件不重复,③不是外部管理的初始化方法),如果合法,则调用该方法。
+
+`init-method` 是通过反射执行的,而 `afterPropertiesSet()` 是直接执行的。所以 `afterPropertiesSet()` 的执行效率比 `init-method` 要高;不过 `init-method` 消除了 Bean 对 Spring 依赖。
+
+其实,按照一种方式设置即可。如果两者同时存在,则按照上述顺序执行。示例见上面的 `ApplicationContextAware` 示例。
+
+== `DestructionAwareBeanPostProcessor`
+
+能否在 Bean 销毁之前,对其做些操作呢?答案是可以的。
+
+`DestructionAwareBeanPostProcessor` 就可以实现这个功能。先来看一下接口定义:
+
+[{java_src_attr}]
+----
+include::{beans_src_dir}/factory/config/DestructionAwareBeanPostProcessor.java[]
+----
+
+由于 `DestructionAwareBeanPostProcessor` 是 `BeanPostProcessor` 子类,由此可见,可以像操作 `BeanPostProcessor` 一样来操作 `DestructionAwareBeanPostProcessor` 实现类。示例如下:
+
+
+[{java_src_attr}]
+----
+public class LogDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
+ @Override
+ public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
+ System.out.println(getAndIncrement()
+ + "LogDestructionAwareBeanPostProcessor.postProcessBeforeDestruction");
+ System.out.println(bean.getClass().getName());
+ }
+}
+
+// 将其注册到 BeanFactory 上
+beanFactory.addBeanPostProcessor(new LogDestructionAwareBeanPostProcessor());
+----
+
+调用是在 `org.springframework.beans.factory.support.DisposableBeanAdapter#destroy` 方法中实现的。
+
+当调用 `beanFactory.destroyBean(bean)` 来手动销毁 Bean 时,就会创建 `DisposableBeanAdapter` 实例,然后调用 `destroy()` 来触发这个回调。也是在这个方法中,当调用完回调后,就会触发下面的 `DisposableBean` 回调。
+
+== `DisposableBean` 与 `destroy-method`
+
+想要触发生命周期函数的 `destroy()` 方法,必须要要手动调用 `beanFactory.destroyBean(bean)` 方法才行:
+
+[{java_src_attr}]
+----
+DggDisposableBean dggDisposableBean = applicationContext.getBean(DggDisposableBean.class);
+ConfigurableListableBeanFactory beanFactory = ApplicationContext.getBeanFactory();
+beanFactory.destroyBean(dggDisposableBean);
+----
+
+调用是在 `org.springframework.beans.factory.support.DisposableBeanAdapter#destroy` 方法中实现的。
+
+和 <> 类似,`destroy-method` 也是在 `DisposableBean#destroy()` 之后执行的。如果同时存在,只要两者不重复,则两个同时都会执行。
+
+== `ApplicationListener`
+
+在 `org.springframework.context.support.AbstractApplicationContext#finishRefresh` 中,发布了 `ContextRefreshedEvent` 事件。
+
+// == `ReaderEventListener`
+
+== 整合实践
+
+上面介绍那么多,现在找一些实际项目对整合过程做个分析。先来个简单的。
+
+=== Hibernate 与 Spring 整合
+
+在 Spring 官网中,给出了非常详细的介绍: https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#orm-hibernate[Data Access: Hibernate^]
+
+Hibernate 与 Spring 整合主要涉及下面几个类:
+
+. `LocalSessionFactoryBean` -- 声明 Hibernate 配置信息;或者注入数据库连接池对象。
+. `HibernateTransactionManager` -- 负责处理 Hibernate 的事务。
+
+实例代码:
+
+[source,xml,{source_attr}]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+ product.hbm.xml
+
+
+
+
+ hibernate.dialect=org.hibernate.dialect.HSQLDialect
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+Spring 与 Hibernate 的整合过程还是比较简单的,就是把 Hibernate 的相关对象当做普通的 Bean 注册到 Spring 容器中即可。
+
+另外,还有一种 `HibernateTemplate` 方式,和上面的方式类似,就不再赘述。
+
+原计划还准备添加 Spring 与 MyBATIS 和 Apache Dubbo 整合分析。考虑到本篇内容已经非常长,仔细分析它们的整合过程又需要大篇幅内容,所以,另外单独开文章进行说明。
+
+== 参考资料
+
+. https://www.jianshu.com/p/397c15cbf34a[Spring扩展点总结 - 简书^]
+. https://www.cnblogs.com/v1haoge/p/6106456.html[Spring中Bean的生命周期及其扩展点 - 唯一浩哥 - 博客园^]
+. https://leokongwq.github.io/2017/04/02/spring-expandPoint.html[spring扩展点整理 | 戒修-沉迷技术的小沙弥^]
+. https://juejin.im/post/5da995d25188256a49204d7b[spring源码系列7:Spring中的InstantiationAwareBeanPostProcessor和BeanPostProcessor的区别 - 掘金^]
+. https://juejin.im/post/5d31b1d2518825276a6f9c70[Dubbo源码之Spring整合 - 掘金^]
+. https://blog.csdn.net/canot/article/details/50512217[详细解释Spring与Hibernate的整合原理_java_不能说的秘密的博客-CSDN博客^]
+. https://blog.csdn.net/u012291108/article/details/51886269[bean的加载(九)记录创建bean的ObjectFactory_java_u012291108的博客-CSDN博客^]
diff --git a/truman/src/docs/asciidoc/factory-bean.adoc b/truman/src/docs/asciidoc/factory-bean.adoc
new file mode 100644
index 000000000000..f0fae059c9e0
--- /dev/null
+++ b/truman/src/docs/asciidoc/factory-bean.adoc
@@ -0,0 +1,14 @@
+= `FactoryBean` 详解
+
+[#FactoryBeanTest]
+.FactoryBeanTest
+[{java_src_attr}]
+----
+include::{truman_src_dir}/beans/FactoryBeanTest.java[]
+----
+<1> 获取 `FactoryBean` 的实现类的实例。
+<2> 获取 `FactoryBean` 的 `getObject()` 方法创建的实例。
+
+由 `FactoryBean` 实现类创建的 Bean 实例,在实际 `getBean` 之前,不会创建。 会根据 `isSingleton()` 方法的返回值来决定创建之后是否缓存实例。
+
+`FactoryBean` 实现类创建的 Bean 实例并不是存储在 `singletonObjects` 实例变量中(由 `DefaultSingletonBeanRegistry` 声明, `AbstractBeanFactory` 间接继承了 `DefaultSingletonBeanRegistry`),而是保存在 `factoryBeanObjectCache` 实例变量中(由 `FactoryBeanRegistrySupport` 声明, `AbstractBeanFactory` 直接继承了 `FactoryBeanRegistrySupport`)。具体情况,请参考类图: <>。
\ No newline at end of file
diff --git a/truman/src/docs/asciidoc/hibernate.adoc b/truman/src/docs/asciidoc/hibernate.adoc
new file mode 100644
index 000000000000..fdaa9f4c3adf
--- /dev/null
+++ b/truman/src/docs/asciidoc/hibernate.adoc
@@ -0,0 +1,2 @@
+[#hibernate]
+= 整合 Hibernate
diff --git a/truman/src/docs/asciidoc/images/DataAccessException.png b/truman/src/docs/asciidoc/images/DataAccessException.png
new file mode 100644
index 000000000000..746f17399b99
Binary files /dev/null and b/truman/src/docs/asciidoc/images/DataAccessException.png differ
diff --git a/truman/src/docs/asciidoc/images/TargetSource-invocation-flow.png b/truman/src/docs/asciidoc/images/TargetSource-invocation-flow.png
new file mode 100644
index 000000000000..a35ca2c9d296
Binary files /dev/null and b/truman/src/docs/asciidoc/images/TargetSource-invocation-flow.png differ
diff --git a/truman/src/docs/asciidoc/images/alipay.png b/truman/src/docs/asciidoc/images/alipay.png
new file mode 100644
index 000000000000..e1bb3340e662
Binary files /dev/null and b/truman/src/docs/asciidoc/images/alipay.png differ
diff --git a/truman/src/docs/asciidoc/images/aop-concepts.png b/truman/src/docs/asciidoc/images/aop-concepts.png
new file mode 100644
index 000000000000..85f1243c02e5
Binary files /dev/null and b/truman/src/docs/asciidoc/images/aop-concepts.png differ
diff --git a/truman/src/docs/asciidoc/images/aop-principle.png b/truman/src/docs/asciidoc/images/aop-principle.png
new file mode 100644
index 000000000000..712eebf2d4ca
Binary files /dev/null and b/truman/src/docs/asciidoc/images/aop-principle.png differ
diff --git a/truman/src/docs/asciidoc/images/aop-proxy-call.png b/truman/src/docs/asciidoc/images/aop-proxy-call.png
new file mode 100644
index 000000000000..de6be86ed543
Binary files /dev/null and b/truman/src/docs/asciidoc/images/aop-proxy-call.png differ
diff --git a/truman/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png b/truman/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png
new file mode 100644
index 000000000000..8ece077d3445
Binary files /dev/null and b/truman/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png differ
diff --git a/truman/src/docs/asciidoc/images/aspect-args-flow.png b/truman/src/docs/asciidoc/images/aspect-args-flow.png
new file mode 100644
index 000000000000..3c6f09da245c
Binary files /dev/null and b/truman/src/docs/asciidoc/images/aspect-args-flow.png differ
diff --git a/truman/src/docs/asciidoc/images/aspects-applied-process.jpg b/truman/src/docs/asciidoc/images/aspects-applied-process.jpg
new file mode 100644
index 000000000000..2302777912ce
Binary files /dev/null and b/truman/src/docs/asciidoc/images/aspects-applied-process.jpg differ
diff --git a/truman/src/docs/asciidoc/images/cglib-architecture.jpg b/truman/src/docs/asciidoc/images/cglib-architecture.jpg
new file mode 100644
index 000000000000..3a8a9e33656a
Binary files /dev/null and b/truman/src/docs/asciidoc/images/cglib-architecture.jpg differ
diff --git a/truman/src/docs/asciidoc/images/cglib.png b/truman/src/docs/asciidoc/images/cglib.png
new file mode 100644
index 000000000000..899a51d44191
Binary files /dev/null and b/truman/src/docs/asciidoc/images/cglib.png differ
diff --git a/truman/src/docs/asciidoc/images/circular-dependence.jpg b/truman/src/docs/asciidoc/images/circular-dependence.jpg
new file mode 100644
index 000000000000..23fa7ab2b9ce
Binary files /dev/null and b/truman/src/docs/asciidoc/images/circular-dependence.jpg differ
diff --git a/truman/src/docs/asciidoc/images/circular-dependence.png b/truman/src/docs/asciidoc/images/circular-dependence.png
new file mode 100644
index 000000000000..7c1a9e507a10
Binary files /dev/null and b/truman/src/docs/asciidoc/images/circular-dependence.png differ
diff --git a/truman/src/docs/asciidoc/images/container-magic.png b/truman/src/docs/asciidoc/images/container-magic.png
new file mode 100644
index 000000000000..2628e59b00e8
Binary files /dev/null and b/truman/src/docs/asciidoc/images/container-magic.png differ
diff --git a/truman/src/docs/asciidoc/images/create-instance.jpg b/truman/src/docs/asciidoc/images/create-instance.jpg
new file mode 100644
index 000000000000..34453203b6ca
Binary files /dev/null and b/truman/src/docs/asciidoc/images/create-instance.jpg differ
diff --git a/truman/src/docs/asciidoc/images/dirty-read-process.png b/truman/src/docs/asciidoc/images/dirty-read-process.png
new file mode 100644
index 000000000000..f1bf22d3f015
Binary files /dev/null and b/truman/src/docs/asciidoc/images/dirty-read-process.png differ
diff --git a/truman/src/docs/asciidoc/images/dubbo-logo.jpg b/truman/src/docs/asciidoc/images/dubbo-logo.jpg
new file mode 100644
index 000000000000..ad6c4f545352
Binary files /dev/null and b/truman/src/docs/asciidoc/images/dubbo-logo.jpg differ
diff --git a/truman/src/docs/asciidoc/images/java-exceptions.jpg b/truman/src/docs/asciidoc/images/java-exceptions.jpg
new file mode 100644
index 000000000000..9d83d1d8bdf8
Binary files /dev/null and b/truman/src/docs/asciidoc/images/java-exceptions.jpg differ
diff --git a/truman/src/docs/asciidoc/images/manual-new-test.png b/truman/src/docs/asciidoc/images/manual-new-test.png
new file mode 100644
index 000000000000..0e4d40e03a35
Binary files /dev/null and b/truman/src/docs/asciidoc/images/manual-new-test.png differ
diff --git a/truman/src/docs/asciidoc/images/message-flow-broker-relay.png b/truman/src/docs/asciidoc/images/message-flow-broker-relay.png
new file mode 100644
index 000000000000..3cf93fa1439c
Binary files /dev/null and b/truman/src/docs/asciidoc/images/message-flow-broker-relay.png differ
diff --git a/truman/src/docs/asciidoc/images/message-flow-simple-broker.png b/truman/src/docs/asciidoc/images/message-flow-simple-broker.png
new file mode 100644
index 000000000000..9afd54f57c23
Binary files /dev/null and b/truman/src/docs/asciidoc/images/message-flow-simple-broker.png differ
diff --git a/truman/src/docs/asciidoc/images/mvc-context-hierarchy.png b/truman/src/docs/asciidoc/images/mvc-context-hierarchy.png
new file mode 100644
index 000000000000..9c4a950caadb
Binary files /dev/null and b/truman/src/docs/asciidoc/images/mvc-context-hierarchy.png differ
diff --git a/truman/src/docs/asciidoc/images/mvc-context-hierarchy.svg b/truman/src/docs/asciidoc/images/mvc-context-hierarchy.svg
new file mode 100644
index 000000000000..07148744b549
--- /dev/null
+++ b/truman/src/docs/asciidoc/images/mvc-context-hierarchy.svg
@@ -0,0 +1,612 @@
+
+
+
+
\ No newline at end of file
diff --git a/truman/src/docs/asciidoc/images/non-repeatable-read-process.png b/truman/src/docs/asciidoc/images/non-repeatable-read-process.png
new file mode 100644
index 000000000000..9702493efd90
Binary files /dev/null and b/truman/src/docs/asciidoc/images/non-repeatable-read-process.png differ
diff --git a/truman/src/docs/asciidoc/images/oxm-exceptions.graffle b/truman/src/docs/asciidoc/images/oxm-exceptions.graffle
new file mode 100644
index 000000000000..4b72bf45285b
--- /dev/null
+++ b/truman/src/docs/asciidoc/images/oxm-exceptions.graffle
@@ -0,0 +1,1619 @@
+
+
+
+
+ ActiveLayerIndex
+ 0
+ ApplicationVersion
+
+ com.omnigroup.OmniGraffle
+ 137.11.0.108132
+
+ AutoAdjust
+
+ BackgroundGraphic
+
+ Bounds
+ {{0, 0}, {756, 553}}
+ Class
+ SolidGraphic
+ ID
+ 2
+ Style
+
+ shadow
+
+ Draws
+ NO
+
+ stroke
+
+ Draws
+ NO
+
+
+
+ CanvasOrigin
+ {0, 0}
+ ColumnAlign
+ 1
+ ColumnSpacing
+ 36
+ CreationDate
+ 2009-09-11 10:15:26 -0400
+ Creator
+ Thomas Risberg
+ DisplayScale
+ 1 0/72 in = 1 0/72 in
+ GraphDocumentVersion
+ 6
+ GraphicsList
+
+
+ Class
+ LineGraphic
+ FontInfo
+
+ Font
+ Helvetica
+ Size
+ 18
+
+ ID
+ 42
+ Points
+
+ {334.726, 144}
+ {394.042, 102.288}
+
+ Style
+
+ stroke
+
+ HeadArrow
+ FilledArrow
+ TailArrow
+ 0
+
+
+
+
+ Class
+ LineGraphic
+ FontInfo
+
+ Font
+ Helvetica
+ Size
+ 18
+
+ ID
+ 41
+ Points
+
+ {489.5, 143.713}
+ {430.452, 102.287}
+
+ Style
+
+ stroke
+
+ HeadArrow
+ FilledArrow
+ TailArrow
+ 0
+
+
+
+
+ Class
+ LineGraphic
+ FontInfo
+
+ Font
+ Helvetica
+ Size
+ 18
+
+ Head
+
+ ID
+ 4
+
+ ID
+ 40
+ Points
+
+ {230, 217}
+ {275.683, 175.337}
+
+ Style
+
+ stroke
+
+ HeadArrow
+ FilledArrow
+ TailArrow
+ 0
+
+
+
+
+ Class
+ LineGraphic
+ FontInfo
+
+ Font
+ Helvetica
+ Size
+ 18
+
+ Head
+
+ ID
+ 4
+
+ ID
+ 39
+ Points
+
+ {430.381, 216.81}
+ {329.369, 175.19}
+
+ Style
+
+ stroke
+
+ HeadArrow
+ FilledArrow
+ TailArrow
+ 0
+
+
+ Tail
+
+ ID
+ 5
+
+
+
+ Bounds
+ {{56, 217}, {249, 30}}
+ Class
+ ShapedGraphic
+ FontInfo
+
+ Font
+ Helvetica
+ Size
+ 18
+
+ ID
+ 6
+ Shape
+ Rectangle
+ Text
+
+ Text
+ {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf540
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\deftab720
+\pard\pardeftab720\qc
+
+\f0\fs36 \cf0 MarshallingFailureException}
+
+
+
+ Bounds
+ {{325.5, 217}, {283.5, 30}}
+ Class
+ ShapedGraphic
+ FontInfo
+
+ Font
+ Helvetica
+ Size
+ 18
+
+ ID
+ 5
+ Shape
+ Rectangle
+ Text
+
+ Text
+ {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf540
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\deftab720
+\pard\pardeftab720\qc
+
+\f0\fs36 \cf0 UnmarshallingFailureException}
+
+
+
+ Bounds
+ {{184, 145}, {217, 30}}
+ Class
+ ShapedGraphic
+ FontInfo
+
+ Font
+ Helvetica
+ Size
+ 18
+
+ ID
+ 4
+ Shape
+ Rectangle
+ Text
+
+ Text
+ {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf540
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\deftab720
+\pard\pardeftab720\qc
+
+\f0\fs36 \cf0 MarshallingException}
+
+
+
+ Bounds
+ {{430, 145}, {239, 30}}
+ Class
+ ShapedGraphic
+ FontInfo
+
+ Font
+ Helvetica
+ Size
+ 18
+
+ ID
+ 3
+ Shape
+ Rectangle
+ Text
+
+ Text
+ {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf540
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\deftab720
+\pard\pardeftab720\qc
+
+\f0\fs36 \cf0 ValidationFailureException}
+
+
+
+ Bounds
+ {{294, 72}, {244, 30}}
+ Class
+ ShapedGraphic
+ FontInfo
+
+ Font
+ Helvetica
+ Size
+ 18
+
+ ID
+ 1
+ Shape
+ Rectangle
+ Style
+
+ Text
+
+ Text
+ {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf540
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\deftab720
+\pard\pardeftab720\qc
+
+\f0\i\fs36 \cf0 XmlMappingException}
+
+ Wrap
+ NO
+
+
+ GridInfo
+
+ GuidesLocked
+ NO
+ GuidesVisible
+ YES
+ HPages
+ 1
+ ImageCounter
+ 1
+ KeepToScale
+
+ Layers
+
+
+ Lock
+ NO
+ Name
+ Layer 1
+ Print
+ YES
+ View
+ YES
+
+
+ LayoutInfo
+
+ Animate
+ NO
+ circoMinDist
+ 18
+ circoSeparation
+ 0.0
+ layoutEngine
+ dot
+ neatoSeparation
+ 0.0
+ twopiSeparation
+ 0.0
+
+ LinksVisible
+ NO
+ MagnetsVisible
+ NO
+ MasterSheets
+
+ ModificationDate
+ 2009-09-11 10:38:54 -0400
+ Modifier
+ Thomas Risberg
+ NotesVisible
+ NO
+ Orientation
+ 2
+ OriginVisible
+ NO
+ PageBreaks
+ YES
+ PrintInfo
+
+ NSBottomMargin
+
+ float
+ 41
+
+ NSLeftMargin
+
+ float
+ 18
+
+ NSOrientation
+
+ int
+ 1
+
+ NSPaperSize
+
+ size
+ {792, 612}
+
+ NSRightMargin
+
+ float
+ 18
+
+ NSTopMargin
+
+ float
+ 18
+
+
+ PrintOnePage
+
+ QuickLookPreview
+
+ JVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmls
+ dGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGVlk1vG0cMhu/zK3h0Dx4Ph/N5rZsA
+ DRCgqdW0V0GVGhkryZGdoj+/L2e1q4W1cloLhhZrfr0PORx/pU/0lRw+OSaKUei4pt9p
+ T84m135oS3f3z0yrZ+L2eV7RrbPx9Nfz0ymAQYAN3f2yPq7WTy/flh0dt0jhU2ppoidf
+ hIIkWu3o7ucd00+HVoRPPFgEriRJTG/hRwupgwVnUYtTDBksxI1ZhION5Csqb3mCGfLk
+ c56pQeyD3P267pYv27/X94fucNzu1i/H7Uo1+BooRCYfAonrZTJ9AJPHntD9Q6vO0cM9
+ BPdJbvVLsaIIDZAhv/kr5wfoBltvwNYRuDrAnngGThTADb4/LohLC3+L79tSbQwZDDMt
+ oO49W4eEi425+WPXfVw+PW33f737RxuwPex/oMUjvVsg2ZtNDeJIciEPyoO+STGjDLXj
+ AHLNbqpDZ2RORwwol6S2hr5Swi7aUpVMr8SflNDN53PdkzLeilWj9d7ly1DLbvsnenrY
+ v19uu2/H9Ws05jtouKDlioYz0KjkzbRPIxq1a2ianY7I0OJraHz1PZq5Jkc0WWqkbFqT
+ z2g+Lo/PX5Zd9/+7bMQjKkQkPYbt6bqc3lZFT20HSVenNmXrkcK3k/e63R6nMpZxcJsm
+ s9jQzW/73VnVlT59b4Sxwpqy8PYEw6yJamb/ZYC5YM2pIt1IrxWxWBdlZuomXZrTYy6O
+ 5GTMx5HCabNSOKDiZIvDNOxIpNjowZdzsTVxNd0waG1P6zpv51CELXtsH8nZuhJzc85W
+ cvV4x9anINQhYLUpKY6MJNwCfsHbS+8NAn/A7+Ps/I8enKOtjNg7I3LKx4VtFtQwycfI
+ x6Uw3k3ynb2brNOSNXN4PI6j9hLbNRUrSQ9gwVC5gpA6qT4H6zP2i0qT4kszxWNI1UgW
+ 6x2msYMdOOutU2zOIKYFzfleB6CzMXqosMTY9lpYnw3dqjaDyjkb9gU2VlAkk2yDr9lN
+ 5c8CD3oRYOWIzQzYuFYxGTHhlcu2ZqhtFEwQZZJxgWEVJ48rRG3Ra5GId9hBudUVgutp
+ hZBtKNI35sIblV3noJts9GAnmLaiHMZ8zM4G36gP+YxeA5FTbSTmvLWXw207NwgiwWaf
+ wCKgOimYP8DoORSvhDWCYN2Ggk3eODD+OVBbNAFDg3fQrBwxoCXjQNRoGpsk/TzMeb/N
+ YfRoHHB8W22nfE2zL+1AnPJRYyOpn4gLb1SrKj79C2PwIN4KZW5kc3RyZWFtCmVuZG9i
+ ago1IDAgb2JqCjkyNgplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50
+ IDMgMCBSIC9SZXNvdXJjZXMgNiAwIFIgL0NvbnRlbnRzIDQgMCBSIC9NZWRpYUJveCBb
+ MCAwIDc1NiA1NTNdCj4+CmVuZG9iago2IDAgb2JqCjw8IC9Qcm9jU2V0IFsgL1BERiAv
+ VGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9Db2xvclNwYWNlIDw8IC9DczIg
+ MTggMCBSCi9DczEgNyAwIFIgPj4gL0ZvbnQgPDwgL0YxLjAgMTkgMCBSIC9GMi4wIDIw
+ IDAgUiA+PiAvWE9iamVjdCA8PCAvSW0yIDEwIDAgUgovSW0zIDEyIDAgUiAvSW00IDE0
+ IDAgUiAvSW01IDE2IDAgUiAvSW0xIDggMCBSID4+ID4+CmVuZG9iagoxMCAwIG9iago8
+ PCAvTGVuZ3RoIDExIDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dp
+ ZHRoIDUyMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQoyMSAwIFIgL1NNYXNrIDIyIDAg
+ UiAvQml0c1BlckNvbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVh
+ bQp4Ae3QMQEAAADCoPVPbQhfiEBhwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+ AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+ wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+ GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+ AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+ wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+ GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+ AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+ wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+ GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+ AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+ wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+ GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+ AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+ wIABAwYMGDBgwIABAwYMvAMDfE4AAQplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjcz
+ NAplbmRvYmoKMTIgMCBvYmoKPDwgL0xlbmd0aCAxMyAwIFIgL1R5cGUgL1hPYmplY3Qg
+ L1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA0NzggL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UK
+ MjQgMCBSIC9TTWFzayAyNSAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9G
+ bGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T+1pCYhAYcCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOADA0auAAEKZW5kc3RyZWFtCmVuZG9iagox
+ MyAwIG9iago2NzQKZW5kb2JqCjE0IDAgb2JqCjw8IC9MZW5ndGggMTUgMCBSIC9UeXBl
+ IC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNjEyIC9IZWlnaHQgMTA0IC9D
+ b2xvclNwYWNlCjI3IDAgUiAvU01hc2sgMjggMCBSIC9CaXRzUGVyQ29tcG9uZW50IDgg
+ L0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dCBAAAAAMOg+VNf4AiFUGHA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgIE/MOn+AAEKZW5kc3RyZWFtCmVuZG9iagoxNSAwIG9iago4NTYK
+ ZW5kb2JqCjE2IDAgb2JqCjw8IC9MZW5ndGggMTcgMCBSIC9UeXBlIC9YT2JqZWN0IC9T
+ dWJ0eXBlIC9JbWFnZSAvV2lkdGggNTQyIC9IZWlnaHQgMTA0IC9Db2xvclNwYWNlCjMw
+ IDAgUiAvU01hc2sgMzEgMCBSIC9CaXRzUGVyQ29tcG9uZW50IDggL0ZpbHRlciAvRmxh
+ dGVEZWNvZGUgPj4Kc3RyZWFtCngB7dAxAQAAAMKg9U9tCy+IQGHAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED
+ BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA
+ gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY
+ MGDAgAEDBgy8BwaUrgABCmVuZHN0cmVhbQplbmRvYmoKMTcgMCBvYmoKNzYxCmVuZG9i
+ ago4IDAgb2JqCjw8IC9MZW5ndGggOSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUg
+ L0ltYWdlIC9XaWR0aCA1MzIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKMzMgMCBSIC9T
+ TWFzayAzNCAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29k
+ ZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T20KP4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+ DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+ AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+ YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMDAa2CIfgABCmVuZHN0
+ cmVhbQplbmRvYmoKOSAwIG9iago3NDcKZW5kb2JqCjIyIDAgb2JqCjw8IC9MZW5ndGgg
+ MjMgMCBSIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTIyIC9I
+ ZWlnaHQgMTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50
+ IDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3tT1PZFsZBCqXvLZS2
+ 9GVaTgvtaSmdY4sFCtM2bXhHFISpM0LQqhkYkNHYSAZ1MIwSiSI4EF6iyBDRgEPAECVG
+ zfxrd53CvXOFcrD3fto96/lATDYmez/rl7XXaTlrZWWh0AF0AB1AB9ABdAAdQAfQAXQA
+ Hfh/HMhGZaADaREB5z/xj3JQGeHAPxE9AQH+CiD2KICzCwS5qIxzQCCA0LJQHAdDkoM9
+ CPKEwvw9iVDEO7AfSqEwD+AGHI5hYZ+D3Nw8gEAkFkskEqlUKkNlgAMQSAinWCzKz2dp
+ 4GaBBSEH7gTAACCQyuRyhVKpQmWIA0qlQi6XAQ9igGGPhSOuiCQIkA9YDmRyhUpVUKhW
+ FxVpNFoU8Q5oNEVFanVhgUqlkMtYFiAvwBWRGgU2I7AJgeVACRRotLpivd5gNJpQxDtg
+ NBr0+mKdVgM0KJMsQFpgUUjxEJEEAQoEiRQ4AAyAAZPZYimhrKgMcIAqsVjMJuABYAAW
+ pBK2XEiNQjZbIwhFkBBUhRqdHiigrKVldgdNO50uFNEOOJ007bCXlVopoEGv0xSqIC2I
+ hGzdeDgpQEoAEPIlMoVKrdWbLJStjHaWuz0ehmFOogh3AILo8bjLnXSZjbKY9Fq1SiGD
+ rJArSHE/QEqAYlGcBMFgpkodLreH8Vae8lfXgAIogh1gI1jtP1XpZTxul6OUMhuSKIih
+ bEyRFLIhJeSLpXKVWmcwW+2uCsbnrw7UBUPhSCQSRRHtAIQwHArWBar9PqbCZbeaDTq1
+ Si4V50NSOHg97KUECYCgNVhstJvxVQWC4Wh9Y1NLa9tpFOEOtLW2NDXWR8PBQJWPcdM2
+ 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
+ Wlpmd9C00+lCEe2A00nTDntZqZWymE16naZQJZdJRADCoXqR/etWSApQNEJWkMqVBWqN
+ Vm8wAg2WEsqKygAHqBILUGA06LUadYFSLoWMwN4NKVLCPgpwQYghLSgLCgEGXbEeeDCa
+ UMQ7YAQG9MU6wKAQOJBJxHA1HAVCVnYyK8CzZJIFhUoFNKiLijQaLYp4BzSaoiI1UKBS
+ KZIcQLGYBOHAhwn7rz4kURDkQloAFiRSmVyuUCpVqAxxQKlUyOUyqQTyAZsQoEY4kZ0a
+ BLgfICuwdSNbLuSLxICDRCqVylAZ4AAEEsIpFosAA8gHLAdHg8CWjXssAAxAA+CQlAhF
+ vAP7oRSyFOQKjuUg+QjBsnAiJydHwOKAyjAHAIIcNh1w5oP9aoFNDEka2N8Hwf9EZYAD
+ e9FM/oQA/yfYX/MP+H1UxjnwNZHH30EH0AF0AB1AB9ABdAAdQAfQAXTgaAf+BYU9EtcK
+ ZW5kc3RyZWFtCmVuZG9iagoyMyAwIG9iagoyNzE5CmVuZG9iagoyOCAwIG9iago8PCAv
+ TGVuZ3RoIDI5IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRo
+ IDYxMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNv
+ bXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d7U9T2RaH
+ BQql7y2U03LaTutpS3taS+fYaoXitKRNESm+oDh1FIJWzVSLHY2NzaAOxlEi8Q1HghhF
+ xohGHSKGqDGjmX/trl3MnTt290jvyf101+8DMfvI/vDkyVq7B9hrwwYMEkACSAAJIAEk
+ gASQABJAAkgACSCB/wWBOgwSWD+B2hSEfev/TgMGCYgR+FuVejBnPaqt+QV7ymSNGCSw
+ XgIyGThDdPuqZmXD1vRqksub16LAIIFqBD47Ipc3gY0g2tcs+2xYY2MT6KVQKlUqlVqt
+ 1mCQQHUCYAh4olQqmpuJZ1+xjCjWAB0SBAO91BqtVqfXGzBIQJyAXq/TajVgmhI0W7Os
+ WsMsKwY1jBim0eoMhpZWo7GtjWFMGCRQjQDDtLUZja0tBoNOqyGWQS2DhllFMlLFSBEj
+ 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
+ WX1DQ4OMiIZBAusjAHo1kBImXsM+n8pIMSt7Rr4BAt+KQQLVCaxpUv4K5vzbonX9A74B
+ gwTWS2BdTuF/QgJIAAkgASSABJAAEkACSAAJIAEkUDuBfwFWtww3CmVuZHN0cmVhbQpl
+ bmRvYmoKMjkgMCBvYmoKMzAwNwplbmRvYmoKMzEgMCBvYmoKPDwgL0xlbmd0aCAzMiAw
+ IFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA1NDIgL0hlaWdo
+ dCAxMDQgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkgL0JpdHNQZXJDb21wb25lbnQgOCAv
+ RmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHtnetPU+kWxrkUer9B2S29TMtu
+ ueyW0tlSLFCclrQBykXkOnUUghTNwICMxkYyqINhlEgUwYFwiSJDRAMOAUOUGDXzr521
+ CzlzhLKZnk/nvHs9H4zJWz+sZ/1ca+1e3pWWhkIH0AF0AB1AB9ABdAAdQAfQAXTg/9GB
+ dJRAHEiJTvAk429looh14O8sZ0DS/wEkB2SAHyJRFkoQDohEkG4OlNMASbBxAEa2WCw5
+ kBRFpAOH6RWLs+E/ASByCh+HbGRlZQMYUplMLpcrFAolilAHILmQYplMKpFwhPDzwcGR
+ Cf0E0AAwFEqVSq3RaFEEO6DRqFUqJTAiA0AO+DihvSTggLrBsaFUqbXanFydLi+PovQo
+ Ih2gqLw8nS43R6tVq5QcH1A/oL0kx4OrHFzh4NjQABmU3pBvNJrMZguKSAfMZpPRmG/Q
+ U0CIJsEHlA8OjyQPLwk4YOCQK4ANQAO4sFhttgLajiLUAbrAZrNagBEABPhQyLnxIzke
+ 6dzMIZZC4dDmUgYjkEHbC4uKSxjG6XShiHPA6WSYkuKiQjsNhBgNVK4WyodUzM2mx4sH
+ lA6AQyJXqrU6vdFiox1FjLPU7fGwLHsGRaADkFiPx13qZIoctM1i1Ou0aiVUjyxRkt4C
+ pQMGUlkCDpOVLixxuT1secVZX1U1yI8izAEuq1W+sxXlrMftKimkraYEHjIYTZMUj3Qo
+ HRKZQqXVGUxWe7GrjPX6qvznAsHaUCgURhHnAKS1Nhg456/yedkyV7HdajLotCqFTALF
+ 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
+ YQ5wWa3yna0oZz1uV0khzbUVrRr6SrLSAbUDiodYIk/gYbTYaEcR4yx1ezwsy55BEegA
+ JNbjcZc6mSIHbbMYE3DIJWIoHUfHDviSKcylgIdUrlRpcymD0WK10fbCouIShnE6XSji
+ HHA6GaakuKjQTtusFqOBytWqlHIpwHFsJuW+gQzFIzMrG6qHQqXJ0VF6o8kMhNgKaDuK
+ UAfoAhuQYTYZ9ZQuR6NSQOXg+kqS0nGIBzQXGZQPTU4uAGLINwIjZguKSAfMwIUx3wBo
+ 5AIbSrkM2spJcKSlJ6pHVrYkwYdaqwVCdHl5FKVHEekAReXl6YAMrVadYAMG0gQcR94K
+ O/xpSwIPURaUD+BDrlCqVGqNRosi2AGNRq1SKRVyqBtc4YCZIyM9ORzQW6B6cLMpN35I
+ pDJARK5QKJQoQh2A5EKKZTIpoAF1g2PjZDi40fSADwAECAFEEpKiiHTgML1ijows0als
+ JB5dOD4yMjMzRRwiKAE4AGBkcmWDt24cTh9cAUkQwr0eBP8SRagDBxlO/AlJ/zcA/+Qv
+ 8HqUIBz4JzTga9ABdAAdQAfQAXQAHUAH0AF0AB3433PgX6y7qcQKZW5kc3RyZWFtCmVu
+ ZG9iagozMiAwIG9iagoyNzYyCmVuZG9iagoyNSAwIG9iago8PCAvTGVuZ3RoIDI2IDAg
+ UiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRoIDQ3OCAvSGVpZ2h0
+ IDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNvbXBvbmVudCA4IC9G
+ aWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d/U8T2RfGeSn0fToD7bRM222Z
+ Uui0lO4IWAFdIBAUAV9Q3LorBK2ahQW7GhubRV0Mq8RGEVwIL1FkiWjAJWCIErOa/de+
+ Z4rZXaEdvt2f7iTn+cFoLiaH58Nz723pnJOTg0IH0AF0AB1AB9ABdAAdQAfQgf/mQC5K
+ IQ5kxRe+p7x/lI8i1oF/KOUBtP8D8g5Z+H5UqgKUIhxQqQCXBHo/wCm2O2AL1WrNjrQo
+ Ih34jEetLoQfQkC8D9/PbAsKCgGsVqfT6/UGg8GIItQBgAOIdDqtRiMRlucrwc2H/RjQ
+ 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
+ KjV28CWuS69cQdl18MXu28Q12JYtKLvu29g5n8Du+HIlZdM5Px+nXhA42UKupGymXkjz
+ iHBiDYGDaTKWlNXEGpw2ReBEKbmSspg2hZPiiBsFt09B2UyKwymPxI1x3Keg7KY84oRW
+ IsewyhSVzYRWaTA6TlcmcIpyppKymK6cg5PRiZt9Ll9QNpPRga4UXp3RJM1Gd/FeXyAY
+ EqtrD4br6kENKMIckKjUhQ/WVouhYMDn5aXB2YwJJmcX7h2dnQN081QFao0+hZdzuvmy
+ csFfGQyFRFE8gCLQAQATCgUr/UJ5Ge92cim4eo26QJW3e7gyfMgKwgt4tXojxRSzNs7p
+ cvMeb3mFTxD8/gCKOAf8fkHwVZR7Pbzb5eRsbDFDGfUwN1u1Z+q99Ak6CC/szZBeA0UX
+ mVkrZ3cAYXcp70ER6gBf6gayDjtnZc1FNGWA5Er7cprofsYLm7MO4ksXFQNgWwkHjB1O
+ FJEOOIArV2IDtMXA1qjXwbacCW5Obiq9cLVK8TUxDBA2Wywsa0UR6QDLWixmIMswphRb
+ uFCl4H4x8eLvDzan8KoKIL7AV28wUpSJphkUwQ7QtImijAY95FYKLpy5ebnp4cLeDOmV
+ 7lbS8avR6gCx3mAwGFGEOgBwAJFOpwW0kFuJbWa40tVqhy8ABsKAOCUtikgHPuNRS2QL
+ VPuyTV2dJb55+fn5KgkxSgEOANh8Kbayuf3X+ZsiLH09CP4nilAHdgil/szNeN7+zfWL
+ v8DXoxThwBfY8B/oADqADqAD6AA6gA6gA+gAOpCFA/8DclEtHwplbmRzdHJlYW0KZW5k
+ b2JqCjI2IDAgb2JqCjI1NTgKZW5kb2JqCjM0IDAgb2JqCjw8IC9MZW5ndGggMzUgMCBS
+ IC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTMyIC9IZWlnaHQg
+ MTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50IDggL0Zp
+ bHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3rT1PpFsZBCqX3Fnqjl2nZbaG7
+ pXS2LZZSmLZpwx1REKbOCEGrZmBARmMjGdTBMEokiuBAuESRIaIBh4AhSoya86+dtQvn
+ zBHKxp7k5CTvXs8HY7Lxw3rWL8+7drHvyslBoQPoADqADqAD6AA6gA6gA+gAOvD/ciAX
+ RbQDWXEFTpz4W3kowhz4u7cnoNVfgcYeD+CCQJCPItgBgQCazOJxHBZpIvZwKBAKC/ck
+ QhHkwH5ThcICAB7AOIaKfSLy8wsAB5FYLJFIpFKpDEWUA9BSaKxYLCosZLngpoJFIg9O
+ DAACcJDK5HKFUqlCEeeAUqmQy2VAhhiw2KPiiAMkjQRkBEuETK5QqYqK1WqNRqvVoQhy
+ QKvVaNTq4iKVSiGXsVRAVsABkhkKNiXYkGCJUAIPWp2+xGAwmkxmFEEOmExGg6FEr9MC
+ F8o0FRAVLBQZXkDSSMAgIZECEQAE0GC2WK2llA1FlANUqdVqMQMZgAVQIZWwY0VmKHLZ
+ WUIogpBQFWv1BuCBsjnKyp007XK5UYQ44HLRtLO8zGGjgAuDXlusgqgQCdlJ83BQQEwA
+ EoUSmUKl1hnMVspeRrsqPF4vwzAnUcQ4AO30ej0VLrrMTlnNBp1apZBBUuQLMpweEBMw
+ XorTSBgtlMPp9ngZX9WpQLAGFEIR4QDby2DgVJWP8XrcTgdlMaahEMOgmSEociEmCsVS
+ uUqtN1ps5e5Kxh8IhurCkWgsFoujCHEAmhmNhOtCwYCfqXSX2yxGvVoll4oLISgOHh57
+ MSEBJHRGq532MP7qUDgar29samltO40ixoG21pamxvp4NByq9jMe2m5lk0IuyRQULBNw
+ cigBCYud9voCtZFYQ3Nbe0dnV3cCRZAD3V2dHe1tzQ2xSG3A56Xt7PGhlEFQHDo84Ogo
+ KJTIi7QGi42u9NeE402tZ88lfuzp7buUTF5GEeJAMnmpr7fnx8S5s61N8XCNv5K2WQza
+ IjYoDh0euSfgPRRiQm+myj2+mkh9y5mu8z19yav9Pw8OXRtGEeLAtaHBn/uvJvt6zned
+ aamP1Pg85ZRZD0EB76MHBwr26IBpQmuwOtxMIFzf2pG4cPFK/+DwjZupWyMoYhy4lbp5
+ Y3iw/8rFC4mO1vpwgHE7rAYtO1HA4fHlR5lpJhTFOjPlrPTXxgGJ3mT/0PXUyOidu2P3
+ UMQ4MHb3zuhI6vpQf7IXoIjX+iudlFlXrMjIRIFIqlSXWOxupjrSdCbRe3lgODVyZ2z8
+ /sTDSRQxDjycuD8+dmckNTxwuTdxpilSzbjtlhK1UioqOJQTggKRjD06yjz+UKyt60Jy
+ 4JfU6NjvE5OPn0w/RRHjwPSTx5MTv4+Npn4ZSF7oaouF/J4y9vCQiWDIPHB2CIRieZHO
+ RDm9ge8azp6/+NNwavTeg8mpmdm5hYVFFCEOLCzMzc5MTT64N5oa/uni+bMN3wW8Tsqk
+ K5KLhRmYkMhhnLC5mGC0+VzPlUFAYuLR9Oz80rPlFysoQhx4sfxsaX52+tEEQDF4pedc
+ czTIuGwwUMglGZiA1w51yTeOCh8cHYm+/usjvz14NDO3+Hxl9eXaKxQhDqy9XF15vjg3
+ 8+jBbyPX+/sScHj4KhzflKjhxeNQTsCrqELNjhNVdfXtPyQHU7fHJ6fnlpb/XHu9vvEG
+ RYgDG+uv1/5cXpqbnhy/nRpM/tBeX1fFDhRq9sXj4DwBTCiBiXJvINzY0XN1eGRsYmp2
+ cXn11cabza1tFCEObG2+2Xi1urw4OzUxNjJ8taejMRzwlgMTyoxMSJUaQymMmJGmzt7+
+ G7+OT87MPwckNrff7qCIceDt9iZA8Xx+ZnL81xv9vZ1NERgySw0apTRTTkhVGiNFfxuM
+ tnT1Ddy8ff/xH0sra+ub2zvv3u+iCHHg/bud7c31tZWlPx7fv31zoK+rJRr8lqaMGtUR
+ TGhNFM3UxFq7Lw2m7k5MzT1bff3X1s673Q8oYhzYfbez9dfr1WdzUxN3U4OXultjNQxN
+ mbRHMwGvosDE98mhW2MPn8wvv1zffAtIfPyEIsSBjx92373dXH+5PP/k4ditoeT3LBMu
+ 27FMtCWS10buTc4svFjb2Np5D0h8RhHiwKePH97vbG2svViYmbw3ci0JL6NHMQG/Ki+U
+ qrSmdE5kYOIfKCIc+MzNxBf/+y43Lx9+3QEfY7pPhuKnE5eHISeeLq68erO9s/vh02ci
+ /MAiwIHPnz7s7my/ebWy+BRyYvhy4nQ8dNINH2TCLzzy85AJPkKCTPCx69w1IxPc/vDx
+ KTLBx65z14xMcPvDx6fIBB+7zl0zMsHtDx+fIhN87Dp3zcgEtz98fIpM8LHr3DUjE9z+
+ 8PEpMsHHrnPXjExw+8PHp8gEH7vOXTMywe0PH58iE3zsOnfNyAS3P3x8ikzwsevcNSMT
+ 3P7w8Skywceuc9eMTHD7w8enyAQfu85dMzLB7Q8fnyITfOw6d83IBLc/fHyKTPCx69w1
+ IxPc/vDxaTZM4HeIeUFINt8hzjmGCUK+aY9lcH+v/MCdqf9x1wDeSULIBSQZyvgv7iTB
+ u4uIuaToiEKyvbsI7zgj5Cazo8vI9o4zvAuRmBsPjy4ku7sQ8c5UQu5F5SojyztT8W5l
+ Qu5P5iojq7uVBXgHOyHXrHOWkdUd7AIh7mogZB8DVxnZ7WrAnS6ErG3hLCO7nS64+4mY
+ /U5chWSz+ykPd8QRsweOq5BsdsSx+0VxlyQxKyOPLCSrXZK4c5aYvbJchWSxcxZ3UxOy
+ fPqYMrLZTY077AlZUn9MGdntsIeBQgxL7HVGi532+gK1kVhDc1t7R2dXdwJFkAPdXZ0d
+ 7W3NDbFIbcDnpe0Wow5W2IvZdeVfXMGek5MLC8sL2C32AIXVTnsYf3UoHI3XNza1tLad
+ RhHjQFtrS1NjfTwaDlX7GQ9ttwIS7Ab7gsNMABQCCAopQKE3Wmzl7krGHwiG6sKRaCwW
+ i6MIcQCaGY2E60LBgJ+pdJfbLEY9ICGFmBAcjIl/BYVYpmCTwkI5nG6Pl/FVnQoEa0Ah
+ FBEOsL0MBk5V+Rivx+10UOzBoVLAyZEpJiAnICiEhZI0FAazlbKX0a4Kj9fLMMxJFDEO
+ QDu9Xk+Fiy6zU1azIY2EpFAIMXE4J9iJAqAQSWRyVbFWbzBbrJTNUVbupGmXy40ixAGX
+ i6ad5WUOG2W1mA16bbFKLpOIAIlDEyb7/3UhKGDMhKSQypVFaq3OYDQBF9ZSyoYiygGq
+ 1Ao8mIwGnVZdpJRLISXYkyNDTOxDAceHGKJCWVQMWOhLDECGyYwiyAET0GAo0QMQxUCE
+ TCKGg+MoJHJy00kBb6RpKhQqFXCh1mi0Wh2KIAe0Wo1GDTyoVIo0ETBeppE48OHE/lc9
+ 0lAI8iEqgAqJVCaXK5RKFYo4B5RKhVwuk0ogI9iQgFniRG5mJOD0gKRgJ012rCgUiQEM
+ iVQqlaGIcgBaCo0Vi0UABGQES8TRSLCD5h4VgAVwAWCkJUIR5MB+U4UsD/mCY4lIv36w
+ VJzIy8sTsGCgiHUAcMhjI4IzI/anCjYs0lywPw+Cf4kiyoG9vqb/hFb/u+1f8xf4eRTB
+ DnwNA/gz6AA6gA6gA+gAOoAOoAPoADqADvxvHPgnR1HeRgplbmRzdHJlYW0KZW5kb2Jq
+ CjM1IDAgb2JqCjI3MDkKZW5kb2JqCjM2IDAgb2JqCjw8IC9MZW5ndGggMzcgMCBSIC9O
+ IDMgL0FsdGVybmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0
+ cmVhbQp4AYWUTUgUYRjH/7ONBLEG0ZcIxdDBJFQmC1IC0/UrU7Zl1UwJYp19d50cZ6eZ
+ 3S1FIoTomHWMLlZEh4hO4aFDpzpEBJl1iaCjRRAFXiK2/zuTu2NUvjAzv3me//t8vcMA
+ VY9SjmNFNGDKzrvJ3ph2enRM2/waVahGFFwpw3M6EokBn6mVz/Vr9S0UaVlqlLHW+zZ8
+ q3aZEFA0KndkAz4seTzg45Iv5J08NWckGxOpNNkhN7hDyU7yLfLWbIjHQ5wWngFUtVOT
+ MxyXcSI7yC1FIytjPiDrdtq0ye+lPe0ZU9Sw38g3OQvauPL9QNseYNOLim3MAx7cA3bX
+ VWz1NcDOEWDxUMX2PenPR9n1ysscavbDKdEYa/pQKn2vAzbfAH5eL5V+3C6Vft5hDtbx
+ 1DIKbtHXsjDlJRDUG+xm/OQa/YuDnnxVC7DAOY5sAfqvADc/AvsfAtsfA4lqYKgVkcts
+ N7jy4iLnAnTmnGnXzE7ktWZdP6J18GiF1mcbTQ1ayrI03+VprvCEWxTpJkxZBc7ZX9t4
+ jwp7eJBP9he5JLzu36zMpVNdnCWa2NantOjqJjeQ72fMnj5yPa/3GbdnOGDlgJnvGwo4
+ csq24jwXqYnU2OPxk2TGV1QnH5PzkDznFQdlTN9+LnUiQa6lPTmZ65eaXdzbPjMxxDOS
+ rFgzE53x3/zGLSRl3n3U3HUs/5tnbZFnGIUFARM27zY0JNGLGBrhwEUOGXpMKkxapV/Q
+ asLD5F+VFhLlXRYVvVjhnhV/z3kUuFvGP4VYHHMN5Qia/k7/oi/rC/pd/fN8baG+4plz
+ z5rGq2tfGVdmltXIuEGNMr6sKYhvsNoOei1kaZ3iFfTklfWN4eoy9nxt2aPJHOJqfDXU
+ pQhlasQ448muZfdFssU34edby/av6VH7fPZJTSXXsrp4Zin6fDZcDWv/s6tg0rKr8OSN
+ kC48a6HuVQ+qfWqL2gpNPaa2q21qF9+OqgPlHcOclYkLrNtl9Sn2YGOa3spJV2aL4N/C
+ L4b/pV5hC9c0NPkPTbi5jGkJ3xHcNnCHlP/DX7MDDd4KZW5kc3RyZWFtCmVuZG9iagoz
+ NyAwIG9iago3OTIKZW5kb2JqCjcgMCBvYmoKWyAvSUNDQmFzZWQgMzYgMCBSIF0KZW5k
+ b2JqCjM4IDAgb2JqCjw8IC9MZW5ndGggMzkgMCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2
+ aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1XiTvU2xs/YwnZ
+ 953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfRvT9Kda97ht99
+ +j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAdnZyRdDOAHtAC
+ Btize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyTTf+oWXDeZCwA
+ CDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5UnBEaHAoAPRQ
+ ABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmIbXEEHAUvQIwh
+ BIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZwVEG9mpAFSIT
+ gAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBIeNaeXQHaggAB
+ oGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8DoOQFQMM7bBgp
+ fG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBDZCAaEJOIb1QS
+ VNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4ROgC6Arpeek96f
+ /h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd2Gc43DiWOYM4
+ v3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoDbmL8YtPilyQc
+ JYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAzVdfSwByS1ZQ8
+ LKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZTtjR2qva+x0sc
+ ph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk6lDusDPhXyKJ
+ UcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2hXREobijxLOMu
+ H604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5iBxmHUWMbT3+
+ OL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/t8I/h3d2fuXC
+ r1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcUzsMDX8iLFC7E
+ QoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGwx8GVYK9O2KMz
+ QI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB/CSBCMFYodPC
+ qSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgHj2O0laVU2FS+
+ qr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnltumi2YP7KYs7y
+ 5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMbS4vj8BbxkcOr
+ +xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2xT2Ln0h4nDhy
+ ejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15lZfS8gkFxwpV
+ Lwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1yI67O7aZuvWj9
+ TsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94XfdehXvUd3b2ag
+ 7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaDp+SnVp9VT3s/
+ F3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZl9veua7QrNS9
+ t3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosEqy1bAvtNjlRO
+ LJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfcUfwPiSxJlOSA
+ lLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXnKhmqOqq/q1Wp
+ O2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMzE1aTKdNGs3Rz
+ bwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6yRmYM3XueR5x
+ nr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJn8g9oWlh9uHI
+ 8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immqbOp8Wl66eQbI
+ aDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7rwozqLo65onnl
+ S0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ubvHmqXqJ+rCGs
+ UbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oyerV71++U9dne
+ pb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZc1mesDGxm3Ik
+ c+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+UiJdUkNyWeqi
+ tL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVFdVwtD8ZdSGP+
+ UIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2YT5sUWEZe5Rs
+ 5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPckeDljTXFq3uI+
+ 7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGaGBN0Kig2OC4k
+ npRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQvMl78lDuV13Wp
+ JD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+oWaydvDFYd/tm
+ fX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698z2rA737yg9LB
+ 2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6pzDssRL7OWapb
+ frCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFSgMTABP8fbh7Y
+ 2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iagozOSAwIG9iagoyNjM0
+ CmVuZG9iagoyNyAwIG9iagpbIC9JQ0NCYXNlZCAzOCAwIFIgXQplbmRvYmoKNDAgMCBv
+ YmoKPDwgL0xlbmd0aCA0MSAwIFIgL04gMyAvQWx0ZXJuYXRlIC9EZXZpY2VSR0IgL0Zp
+ bHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7VeJO9TbGz9jCdn3nck+jKWxJjvZ
+ Q0iWrDOMbQYzdtmibKFEiCwhkexbQpKSrSKSJJQkV9G9P0p1r3uG3336Pb/n9h90vs97
+ zue87znvOd953+f7eQcAVpy+jY0lDQCAQAwl2ZoYIB2dnJF0M4Ae0AIG2LN7YsnBlDVw
+ yU/a1jOAoJieok3sjxrcNx2oe7dJzZI92sinuV6U/JNN/6hZcN5kLAAINFR4kODhAFBx
+ QcyF38MyFOy1h7UomGRvawjX2EBhwu9impMU7LWL9/lScERocCgA9FAAFzaYRMHFEJ/1
+ CtjVp1L04Vg81DNIALCPA+vriQOAVQPq0TgCEWLEOYhtcQQcBS9AjCEEhsF77jbK2zJ5
+ E4/bwdEIihAwBWHAG0QBG2ALrAESGIIgEAiFBLElnBnBUQb2akAVIhOAAQpQkEAfKEGk
+ BB/UT/yr7fp3BPLQsx8IhacggRkgAizcR/EZsfsogEh41p5dAdqCAAGgYEz//c48uz7/
+ 7Y5KAFDiD+2wEfkBMKD8djw/dM69AGTCmAiif+jkvwOg5AVAwztsGCl8by/in4Ea0AFG
+ wA744G1RQAW+sRVwhfdPALmgBvSB5+B3BDNCFmGG8ENkIBoQk4hvVBJU1lQxVDVUM9T7
+ qbWpSdQ11K9phGicaPJppmn5aV1pr9Ku7lPeF7dvhE6ALoCul56T3p/+HoMwQzTDzP5D
+ +4sZEYx4xidMmkzVzDzMZ5m3WYgsb1ndWGfYHNim2B3YZzjcOJY5gzi/caVx83PX8ujy
+ TPES+Oj5KvkN+ZcEUgTRgpNCccIo4WmRFFFN0Y/IqgNuYvxi0+KXJBwlhSTfSN2QDpcx
+ RHGglmQ75LLQPvJ6CsIK3xVfKd09WI05rxytgld1UDNV19LAHJLVlDwspnVAW1xHWldB
+ T01f38Da0N0o5MgZ42KTNtNxs3ULVkvM0RNW8dY1NlO2NHaq9r7HSxymHdmdrJyzXJ64
+ crm5uFd6bHjpYLNxr33U8dm+7/2NA6oIdMSAoImQw6TqUO6wM+FfIolRyzEep+biXOPn
+ E7GnV5PJZ3ZSstJE05vPmWYuZp+6wJ9zK/fkJUR+TaFdEShuKPEs4y4frThbZVCNuN5f
+ e6bOsp67YaGpviW+zbZD5hbomu3u7C3oi+n3GDB9gHmIHGYdRYxtPf44vvL07dTS9PLM
+ 6uynuW8L9K95l2SWtVfsVwlraR+vbwz//nGT+7POtv+3wj+Hd3Z+5cKvXPiVC7++C///
+ XfjBG1tT/60b5H7oQDQkjjgovj/hLn9oE9rl12DItxTOwwNfyIsULsRChkGC/+VKNJxj
+ dvn1IGTQPaS+y5z6kJ8DoZXCqnseyLszb0CGHEsC4bDHwZVgr07YozNAjYDlBawICFQz
+ NMa0zXSi9BkMXxhxTOMs2qy17DwcSZzr3Cd5PHnxfIH8JIEIwVih08KpIpmiF5GFB0rE
+ KsVrJBokL0nFSnvLWKKUZQXlqOTeo8flOxVKFVOUiAePY7SVpVTYVL6qvlEbU+/QKDuU
+ rkk+7Kploq2kI6BLo/tBb03/N4P3hitG7468NV4yeW26aLZg/spizvLl0RdWM9arNl9t
+ Ge2E7NHHtR2sTrg5BjklOJ93KT/Z7Nrv9tR9wWPNcxtLi+PwFvGRw6v7GvnZ+LsG+AeG
+ E5KI2UFVwbdDxknL5O9hHOEyETqRdlF+0fExeaduxPbFPYufSHicOHJ6MOlect+Z7rOd
+ Ka2pjWk302syqs6VZ5Zknc72OW9+QTGHM+fzxZe5fXmVl9LyCQXHClUvC1z+q+hlcdeV
+ /JKwUrsypXKW8rWrwxXVlWeqsNf0q0Wqv1+fq+mpvXIjrs7tpm69aP1Ow0JjX1N5c2KL
+ V6tBm1g7VftiR19n6a24LtfbWt2C3V97Zno77+T3hd916Fe9R3dvZqDuftwDm0Hxwc2H
+ g0OFw4EjOqNso2/G2h6lPDZ6QvXkzvipiUMTW09bJoOn5KdWn1VPez8Xez4/U/zCehYx
+ 2/oSPycwN/YqYR4z/3ahYNFi8a/XjW+wSzxLvW99lpmX2965rtCs1L23f/99teI3i9/+
+ WLv8weDDKoy/ApULdRpNB+0SHQe9HgNhfxHjENMWiwSrLVsC+02OVE4slw6sLf7D84i3
+ hi+Z311AU5BbcENoRLhKJEFUULQdeQy5diBFTEysR9xR/A+JLEmU5ICUu9RX6TwZA5kN
+ 1BVZC9kvctfQdvII+XoFF0UGxXYl3EH2g3cwJGVJ5ecqGao6qr+rVak7ajBq9B4K0ZTQ
+ fH44Q0tHm0Z7SCdb97ieoN6ifrVBoCHG8ItR75FkYzMTVpMp00azdHNvC11LAcvNo4+t
+ aq2TbdyPHbLlsl23G7KvPJ7pEHHCw9HMSdlZyGWfy/rJGZgzde55HnGevl7HsCgcAjfj
+ 3eiTivfw1fBj9XvnfycgPzCIYEwUIW4F9QdnhTiRJEmfyD2haWH24cjwtYjOyOQo62jB
+ 6HcxQ6fqYrPiguPtElQTeRO/nn6Z1JtcfibprHeKaaps6nxaXrp5BshoOxeQicx8lpWR
+ rZ+9db7ugmcOb87oxYxc8zz6vMFLZ/ONCqgL+gsTLuvCjOoujrmieeVLSUspoUy6bLG8
+ +KpDBVvFMMwq3artay3VxOsy11/XpNcq187eSKqTq5u8eapeon6sIaxRuPF+E7GZp7m3
+ JaCVt3WgLbhduH2oI7xTrPPxrZguma7J24nd8t0vejJ6tXvX75T12d6lvtvW73OP797Q
+ QMx99P1XD7IH9WH8tagiqVtpNvah6XzpKxkWGIWYHJlzWZ6wMbGbciRz4rnMuNE8LDyf
+ eJ/ytfMXCMQIugnpCYuL0IqsiA4jIw9IHXgqliiuKP5SIl1SQ3JZ6qK0vvS6TDHKHPVF
+ 9rqcI5oefUveT4FfYUgxSgml9OJgOkYTs6p8WcVclUV1XC0Pxl1IY/5QhabPYdnDH7Sa
+ tEN11HW+6fbqFeiHGFgYShj+ZTR9pMk43QRnqm3Ga7ZhPmxRYRl7lGzlZ+1h43DsqK2h
+ naa90nFpB+ETnI77nYDTZ+cPLrMnH7q2u1W6X/CI9yR4OWNNcWre4j7sPjv4Nd8XfhP+
+ IwEDgd2ENmJ90LXg0pAC0nlyWujpsOhwckRgZGAUIZoYE3QqKDY4LiSelEBKJJ8OTQpN
+ hsXp2YgU11TDNFQ6a/pmxuy5u5nVWZnZ5PNOF3RzJC8yXvyUO5XXdakkP6kAX2hxWamI
+ q2i7eO5Kf8m10vSyoHK7qyYVmpXyVchrXNV01V+vf6hZrJ28MVh3+2Z9fXlDbmNhU2lz
+ ZUtNa31bS3tnR09n/63BrrHbE93TPS97F+98v8vbr3zPasDvfvKD0sHbD58NfRphGpUe
+ M3zk9jjqSdF4z8T8JGJK/JnxtO/z9Jm6F49mN+Y4XqnMOyxEvs5Zqlt+sLKw+vUD17ri
+ J7M/sJuxn/O3m76N/Pl2ZwcAso8yZpcREMzbANAtQVKAxMAE/x9uHtjZ2dmCGeK+s/Mn
+ N0AIhf8N2jTKGQplbmRzdHJlYW0KZW5kb2JqCjQxIDAgb2JqCjI2MzQKZW5kb2JqCjI0
+ IDAgb2JqClsgL0lDQ0Jhc2VkIDQwIDAgUiBdCmVuZG9iago0MiAwIG9iago8PCAvTGVu
+ Z3RoIDQzIDAgUiAvTiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0
+ ZURlY29kZSA+PgpzdHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN2
+ 2aJsoUSILCGR7FtCkpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf
+ 5/t5BwBWnL6NjSUNAIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6i
+ TeyPGtw3Hah7t0nNkj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWH
+ tSiYZG9rCNfYQGHC72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzU
+ 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
+ qu1rLdXE6zLXX9ek1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24
+ fagjvFOs8/GtmC6Zrsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1
+ Yfy1qCKpW2k29qHpfOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6
+ CekJi4vQiqyIDiMjD0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95P
+ gV9hSDFKCaX04mA6RhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV
+ 6IcYWBhKGP5lNH2kyTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROc
+ jvudgNNn5w8usycfura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3Q
+ teDSkALSeXJa6Omw6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0
+ VDpr+mbG7Lm7mdVZmdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS
+ 9LKgcrurJhWalfJVyGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dH
+ T2f/rcGusdsT3dM9L3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjP
+ xPwkYkr8mfG07/P0mboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87eb
+ vo38+XZnBwCyjzJmlxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZ
+ CmVuZHN0cmVhbQplbmRvYmoKNDMgMCBvYmoKMjYzNAplbmRvYmoKMjEgMCBvYmoKWyAv
+ SUNDQmFzZWQgNDIgMCBSIF0KZW5kb2JqCjQ0IDAgb2JqCjw8IC9MZW5ndGggNDUgMCBS
+ IC9OIDEgL0FsdGVybmF0ZSAvRGV2aWNlR3JheSAvRmlsdGVyIC9GbGF0ZURlY29kZSA+
+ PgpzdHJlYW0KeAGFUk9IFFEc/s02EoSIQYV4iHcKCZUprKyg2nZ1WZVtW5XSohhn37qj
+ szPTm9k1xZMEXaI8dQ+iY3Ts0KGbl6LArEvXIKkgCDx16PvN7OoohG95O9/7/f1+33tE
+ bZ2m7zspQVRzQ5UrpaduTk2Lgx8pRR3UTlimFfjpYnGMseu5kr+719Zn0tiy3se1dvv2
+ PbWVZWAh6i22txD6IZFmAB+ZnyhlgLPAHZav2D4BPFgOrBrwI6IDD5q5MNPRnHSlsi2R
+ U+aiKCqvYjtJrvv5uca+i7WJg/5cj2bWjr2z6qrRTNS090ShvA+uRBnPX1T2bDUUpw3j
+ nEhDGinyrtXfK0zHEZErEEoGUjVkuZ9qTp114HUYu126k+P49hClPslgqIm16bKZHYV9
+ AHYqy+wQ8AXo8bJiD+eBe2H/W1HDk8AnYT9kh3nWrR/2F65T4HuEPTXgzhSuxfHaih9e
+ LQFD91QjaIxzTcTT1zlzpIjvMdQZmPdGOaYLMXeWqhM3gDthH1mqZgqxXfuu6iXuewJ3
+ 0+M70Zs5C1ygHElysRXZFNA8CVgUfYuwSQ48Ps4eVeB3qJjAHLmJ3M0o9x7VERtno1KB
+ VnqNV8ZP47nxxfhlbBjPgH6sdtd7fP/p4xV117Y+PPmNetw5rr2dG1VhVnFlC93/xzKE
+ j9knOabB06FZWGvYduQPmsxMsAwoxH8FPpf6khNV3NXu7bhFEsxQPixsJbpLVG4p1Oo9
+ g0qsHCvYAHZwksQsWhy4U2u6OXh32CJ6bflNV7Lrhv769nr72vIebcqoKSgTzbNEZpSx
+ W6Pk3Xjb/WaREZ84Or7nvYpayf5JRRA/hTlaKvIUVfRWUNbEb2cOfhu2flw/pef1Qf08
+ CT2tn9Gv6KMRvgx0Sc/Cc1Efo0nwsGkh4hKgioMz1E5UY40D4inx8rRbZJH9D0AZ/WYK
+ ZW5kc3RyZWFtCmVuZG9iago0NSAwIG9iago3MDQKZW5kb2JqCjE4IDAgb2JqClsgL0lD
+ Q0Jhc2VkIDQ0IDAgUiBdCmVuZG9iago0NiAwIG9iago8PCAvTGVuZ3RoIDQ3IDAgUiAv
+ TiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+Pgpz
+ dHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN22aJsoUSILCGR7FtC
+ kpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf5/t5BwBWnL6NjSUN
+ AIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6iTeyPGtw3Hah7t0nN
+ kj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWHtSiYZG9rCNfYQGHC
+ 72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzUM0gAsI8D6+uJA4BV
+ A+rROAIRYsQ5iG1xBBwFL0CMIQSGwXvuNsrbMnkTj9vB0QiKEDAFYcAbRAEbYAusARIY
+ giAQCIUEsSWcGcFRBvZqQBUiE4ABClCQQB8oQaQEH9RP/Kvt+ncE8tCzHwiFpyCBGSAC
+ LNxH8Rmx+yiASHjWnl0B2oIAAaBgTP/9zjy7Pv/tjkoAUOIP7bAR+QEwoPx2PD90zr0A
+ ZMKYCKJ/6OS/A6DkBUDDO2wYKXxvL+KfgRrQAUbADvjgbVFABb6xFXCF908AuaAG9IHn
+ 4HcEM0IWYYbwQ2QgGhCTiG9UElTWVDFUNVQz1PuptalJ1DXUr2mEaJxo8mmmaflpXWmv
+ 0q7uU94Xt2+EToAugK6XnpPen/4egzBDNMPM/kP7ixkRjHjGJ0yaTNXMPMxnmbdZiCxv
+ Wd1YZ9gc2KbYHdhnONw4ljmDOL9xpXHzc9fy6PJM8RL46Pkq+Q35lwRSBNGCk0Jxwijh
+ aZEUUU3Rj8iqA25i/GLT4pckHCWFJN9I3ZAOlzFEcaCWZDvkstA+8noKwgrfFV8p3T1Y
+ jTmvHK2CV3VQM1XX0sAcktWUPCymdUBbXEdaV0FPTV/fwNrQ3SjkyBnjYpM203GzdQtW
+ S8zRE1bx1jU2U7Y0dqr2vsdLHKYd2Z2snLNcnrhyubm4V3pseOlgs3GvfdTx2b7v/Y0D
+ qgh0xICgiZDDpOpQ7rAz4V8iiVHLMR6n5uJc4+cTsadXk8lndlKy0kTTm8+ZZi5mn7rA
+ n3Mr9+QlRH5NoV0RKG4o8SzjLh+tOFtlUI243l97ps6ynrthoam+Jb7NtkPmFuia7e7s
+ LeiL6fcYMH2AeYgcZh1FjG09/ji+8vTt1NL08szq7Ke5bwv0r3mXZJa1V+xXCWtpH69v
+ DP/+cZP7s862/7fCP4d3dn7lwq9c+JULv74L//9d+MEbW1P/rRvkfuhANCSOOCi+P+Eu
+ f2gT2uXXYMi3FM7DA1/IixQuxEKGQYL/5Uo0nGN2+fUgZNA9pL7LnPqQnwOhlcKqex7I
+ uzNvQIYcSwLhsMfBlWCvTtijM0CNgOUFrAgIVDM0xrTNdKL0GQxfGHFM4yzarLXsPBxJ
+ nOvcJ3k8efF8gfwkgQjBWKHTwqkimaIXkYUHSsQqxWskGiQvScVKe8tYopRlBeWo5N6j
+ x+U7FUoVU5SIB49jtJWlVNhUvqq+URtT79AoO5SuST7sqmWiraQjoEuj+0FvTf83g/eG
+ K0bvjrw1XjJ5bbpotmD+ymLO8uXRF1Yz1qs2X20Z7YTs0ce1HaxOuDkGOSU4n3cpP9ns
+ 2u/21H3BY81zG0uL4/AW8ZHDq/sa+dn4uwb4B4YTkojZQVXBt0PGScvk72Ec4TIROpF2
+ UX7R8TF5p27E9sU9i59IeJw4cnow6V5y35nus50pramNaTfTazKqzpVnlmSdzvY5b35B
+ MYcz5/PFl7l9eZWX0vIJBccKVS8LXP6r6GVx15X8krBSuzKlcpbytavDFdWVZ6qw1/Sr
+ Raq/X5+r6am9ciOuzu2mbr1o/U7DQmNfU3lzYotXq0GbWDtV+2JHX2fprbgu19ta3YLd
+ X3tmejvv5PeF33XoV71Hd29moO5+3AObQfHBzYeDQ4XDgSM6o2yjb8baHqU8NnpC9eTO
+ +KmJQxNbT1smg6fkp1afVU97Pxd7Pj9T/MJ6FjHb+hI/JzA39iphHjP/dqFg0WLxr9eN
+ b7BLPEu9b32WmZfb3rmu0KzUvbd//3214jeL3/5Yu/zB4MMqjL8ClQt1Gk0H7RIdB70e
+ A2F/EeMQ0xaLBKstWwL7TY5UTiyXDqwt/sPziLeGL5nfXUBTkFtwQ2hEuEokQVRQtB15
+ DLl2IEVMTKxH3FH8D4ksSZTkgJS71FfpPBkDmQ3UFVkL2S9y19B28gj5egUXRQbFdiXc
+ QfaDdzAkZUnl5yoZqjqqv6tVqTtqMGr0HgrRlNB8fjhDS0ebRntIJ1v3uJ6g3qJ+tUGg
+ Icbwi1HvkWRjMxNWkynTRrN0c28LXUsBy82jj61qrZNt3I8dsuWyXbcbsq88nukQccLD
+ 0cxJ2VnIZZ/L+skZmDN17nkecZ6+XsewKBwCN+Pd6JOK9/DV8GP1e+d/JyA/MIhgTBQh
+ bgX1B2eFOJEkSZ/IPaFpYfbhyPC1iM7I5CjraMHodzFDp+pis+KC4+0SVBN5E7+efpnU
+ m1x+Jumsd4ppqmzqfFpeunkGyGg7F5CJzHyWlZGtn711vu6CZw5vzujFjFzzPPq8wUtn
+ 840KqAv6CxMu68KM6i6OuaJ55UtJSymhTLpssbz4qkMFW8UwzCrdqu1rLdXE6zLXX9ek
+ 1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24fagjvFOs8/GtmC6Z
+ rsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1Yfy1qCKpW2k29qHp
+ fOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6CekJi4vQiqyIDiMj
+ D0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95PgV9hSDFKCaX04mA6
+ RhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV6IcYWBhKGP5lNH2k
+ yTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROcjvudgNNn5w8usycf
+ ura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3QteDSkALSeXJa6Omw
+ 6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0VDpr+mbG7Lm7mdVZ
+ mdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS9LKgcrurJhWalfJV
+ yGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dHT2f/rcGusdsT3dM9
+ L3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjPxPwkYkr8mfG07/P0
+ mboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87ebvo38+XZnBwCyjzJm
+ lxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZCmVuZHN0cmVhbQpl
+ bmRvYmoKNDcgMCBvYmoKMjYzNAplbmRvYmoKMzMgMCBvYmoKWyAvSUNDQmFzZWQgNDYg
+ MCBSIF0KZW5kb2JqCjQ4IDAgb2JqCjw8IC9MZW5ndGggNDkgMCBSIC9OIDMgL0FsdGVy
+ bmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1X
+ iTvU2xs/YwnZ953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfR
+ vT9Kda97ht99+j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAd
+ nZyRdDOAHtACBtize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyT
+ Tf+oWXDeZCwACDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5
+ UnBEaHAoAPRQABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmI
+ bXEEHAUvQIwhBIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZ
+ wVEG9mpAFSITgAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBI
+ eNaeXQHaggABoGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8D
+ oOQFQMM7bBgpfG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBD
+ ZCAaEJOIb1QSVNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4RO
+ gC6Arpeek96f/h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd
+ 2Gc43DiWOYM4v3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoD
+ bmL8YtPilyQcJYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAz
+ VdfSwByS1ZQ8LKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZT
+ tjR2qva+x0scph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk
+ 6lDusDPhXyKJUcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2h
+ XREobijxLOMuH604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5
+ iBxmHUWMbT3+OL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/
+ t8I/h3d2fuXCr1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcU
+ zsMDX8iLFC7EQoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGw
+ x8GVYK9O2KMzQI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB
+ /CSBCMFYodPCqSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgH
+ j2O0laVU2FS+qr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnlt
+ umi2YP7KYs7y5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMb
+ S4vj8BbxkcOr+xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2
+ xT2Ln0h4nDhyejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15
+ lZfS8gkFxwpVLwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1y
+ I67O7aZuvWj9TsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94Xf
+ dehXvUd3b2ag7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaD
+ p+SnVp9VT3s/F3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZ
+ l9veua7QrNS9t3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosE
+ qy1bAvtNjlROLJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfc
+ UfwPiSxJlOSAlLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXn
+ KhmqOqq/q1WpO2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMz
+ E1aTKdNGs3RzbwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6
+ yRmYM3XueR5xnr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJ
+ n8g9oWlh9uHI8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immq
+ bOp8Wl66eQbIaDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7r
+ wozqLo65onnlS0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ub
+ vHmqXqJ+rCGsUbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oy
+ erV71++U9dnepb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZ
+ c1mesDGxm3Ikc+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+
+ UiJdUkNyWeqitL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVF
+ dVwtD8ZdSGP+UIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2
+ YT5sUWEZe5Rs5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPck
+ eDljTXFq3uI+7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGa
+ GBN0Kig2OC4knpRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQv
+ Ml78lDuV13WpJD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+o
+ WaydvDFYd/tmfX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698
+ z2rA737yg9LB2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6p
+ zDssRL7OWapbfrCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFS
+ gMTABP8fbh7Y2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iago0OSAw
+ IG9iagoyNjM0CmVuZG9iagozMCAwIG9iagpbIC9JQ0NCYXNlZCA0OCAwIFIgXQplbmRv
+ YmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNzU2IDU1M10g
+ L0NvdW50IDEgL0tpZHMgWyAyIDAgUiBdID4+CmVuZG9iago1MCAwIG9iago8PCAvVHlw
+ ZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgL1ZlcnNpb24gLzEuNCA+PgplbmRvYmoKNTEg
+ MCBvYmoKPDwgL0xlbmd0aCA1MiAwIFIgL0xlbmd0aDEgNzE3MiAvRmlsdGVyIC9GbGF0
+ ZURlY29kZSA+PgpzdHJlYW0KeAG9WXtYlNW6f9f3fXNBUG4Kw3Vm+BiugwgooJiMOMNF
+ TFEUGfMygCCSGClSlhK7dJd4OVtNbWtHs4s7JXME0gG2Ru7c6a6dVrub2043szpPPtU5
+ dWqHzJzf+mYk7dn1+EdPfM87613X97d+77vW960FMSIKoDYSyVLTWNVEa2gAJa9AWmta
+ mg2bP5+0l4hNIxKX1TUtaQz+4C9/I5JcRMMClixbXff11rzpRCNeJNIa6murFn+jX9ZN
+ FHYJ/bPrURAwMOIOovBo5OPrG5vvtm1UP4O8BXnLsjtqqkJygxzItyEf11h1d5N25bDv
+ kX8SecPyqsbahPzouchjfEppumNlM3tGqEP+K+QLmlbUNv35geUZRLqxwHcOZQwP/wsg
+ Na1AaqOxvhKlWPkRflSv08TrdK8qIVFB1BANRAsh8qNh5I/xhys5TN2XBqJxPwWpTlCS
+ qo0ipXTSE3nehVzgqXuO57LqJQpyN3q+FvPQp4eL4M6fSP20mfbQEdh5GnoSLaRH6Cxr
+ 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
+ MlwC69SfSnRJSF6IRc4SqO+P2at/PmaJ/iSkw1t1KBktjukPxizTb491sd2d+m0xLoY+
+ W73Jqhh0PaZvTN6pX5yh1E/b6RI6OvXjUV9h8ddn5xr142Iu6dMTXVqGfFrMNH1Kxt/1
+ 8eiIZgYMarIE66NjtusnoCo2xpY4AdLHDrE9lML2dJqm6nuhYrpdJcm5O13s3q7ipAyT
+ i91jyS5O2plcnGhKnqY3JRcmJkKvOKNZp7lNM1mTqUnFBW2CxqiJ0ozUhmiDtCO0Adph
+ Wq1W42LPdObr1X2sg/JBS0eXVq1VudizKJT62GGl8PBxraQVtKQd6fJ8gH/mMBrpYh3d
+ CAxGUI6pFU3tYoexFnjRYYseoYwNRKkIQoTxj2H+SwLTCgghJ9vsUtP6sJZ8XX7IpODx
+ hdaf+3EoNdd+U3/+T8dinDtxF+M8FGPHtRcUT4z9WnPdNeVn0+ZVqKotSE0tnbW6q6Wp
+ oU65xpNttQ7c5jk3tuBata3aYDja0OS7o0xwVNfU83ukqlpnk1xrdTbIVsPRFqUfL76u
+ uo5Xt8jWo1Rnm115tM5Sa+1ssbTY+HVmV3XBigU32NowZGtFwb+xVcAHW8FtVSv9fmJr
+ Aa+u5rYWcFsLuK1qS7Vii0/etrS8YGUzohNXfbhqSyp3lsycV4kbbbvVxQ7w+79V9P+8
+ rYdICmVuZHN0cmVhbQplbmRvYmoKNTIgMCBvYmoKNDM3MQplbmRvYmoKNTMgMCBvYmoK
+ PDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgNzcwIC9DYXBIZWlnaHQgNzI3
+ IC9EZXNjZW50IC0yMzAgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTkzMyAtNDgxIDE1NzEg
+ MTEzOF0gL0ZvbnROYW1lIC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUgL0l0YWxpY0Fu
+ Z2xlCi0xMiAvU3RlbVYgMCAvTWF4V2lkdGggMTUwMCAvWEhlaWdodCA1MzEgL0ZvbnRG
+ aWxlMiA1MSAwIFIgPj4KZW5kb2JqCjU0IDAgb2JqClsgNjY3IDAgMCAwIDAgMCAwIDAg
+ ODMzIDAgMCAwIDAgMCAwIDAgMCAwIDAgNjY3IDAgMCAwIDAgMCAwIDAgMCA1NTYgMCA1
+ MDAKMCA1NTYgMCA1NTYgMCAyMjIgMCAwIDIyMiA4MzMgNTU2IDU1NiA1NTYgMCAwIDAg
+ Mjc4IDAgMCAwIDUwMCBdCmVuZG9iagoxOSAwIG9iago8PCAvVHlwZSAvRm9udCAvU3Vi
+ dHlwZSAvVHJ1ZVR5cGUgL0Jhc2VGb250IC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUg
+ L0ZvbnREZXNjcmlwdG9yCjUzIDAgUiAvV2lkdGhzIDU0IDAgUiAvRmlyc3RDaGFyIDY5
+ IC9MYXN0Q2hhciAxMjAgL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5nCj4+CmVuZG9i
+ ago1NSAwIG9iago8PCAvTGVuZ3RoIDU2IDAgUiAvTGVuZ3RoMSA5OTcyIC9GaWx0ZXIg
+ L0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ab16e3iU1bX32vu9ziWTmcncM5PJZDIzmdxD
+ SMiQQMaQhHsMBCFBggkQCAg1YIyiwkGFIhGpQrkIPVS05RKKGUIKAxQ/ykHR1lPxitdW
+ j2i1T/N4Tg/aVpiZb+13Qgo+/fr5R5/OO/u+373X+q2199qXFwgAaGEdcBBeuKK9C54n
+ 4zHnFXRrF/Z0Zz7+xfi9AGQaALd8cdeSFYaP/uNXAHwUQK1dsnz14rJtr8wH0J0HMF7u
+ 7Ghf9Kf/XX4SwHMQ3y/vxAx1llSE6Y8wnd25ovu+RRUqC0AWj+l5y+9a2F4WHVuO6TZM
+ F69ov69LfkD9V0w/genM77Wv6Jj7wMPbMB3BdFbXXXd3000clmW9ienGrlUdXb945Hsl
+ AN5spO9VzCP4sJ8WRFiFYR2Mxhyq5F33uOuR4ZAH4Vs5yaSIgQQyqDBUgwbbZL8U0EEq
+ 6MGAcSOkgQnMSj5yJZwFvXAGcoR14OCLwA2QeBfdeyyM35b4TLgA+viKxP9wlfgGogQn
+ aby6Cs7C47AH+pHigxjPgfmwC14my+AkmQeD8DbJgEKUDw9RmAavkETiNVgMP8H63XAO
+ tsNRpCsHViAV02AL8SXux3QY4wtgfeIZyIYK+D6cgRC2ugWGEocSx7B0JtwGfXAY3/81
+ 8dKjfFriucRl5HQGtrkeS15LTEv0I3f5UAONmLsetcLHvZfoBBtUInU/gh/DPvgl/JE8
+ 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
+ VrXe1Nemkb5W1fydvmpYY6tYXwuU977VVysrXsD6amV9tbK+FoQXKH0xCOqWNtXc3Y3a
+ iVfbeLWc0xSZPGNuM37B0VIbJfvZffc98H8BcaX7nAplbmRzdHJlYW0KZW5kb2JqCjU2
+ IDAgb2JqCjY2ODkKZW5kb2JqCjU3IDAgb2JqCjw8IC9UeXBlIC9Gb250RGVzY3JpcHRv
+ ciAvQXNjZW50IDc3MCAvQ2FwSGVpZ2h0IDcyNyAvRGVzY2VudCAtMjMwIC9GbGFncyAz
+ MgovRm9udEJCb3ggWy05NTEgLTQ4MSAxNDQ1IDExMjJdIC9Gb250TmFtZSAvWFlVVFBT
+ K0hlbHZldGljYSAvSXRhbGljQW5nbGUgMAovU3RlbVYgOTggL01heFdpZHRoIDE1MDAg
+ L1N0ZW1IIDg1IC9YSGVpZ2h0IDUzMSAvRm9udEZpbGUyIDU1IDAgUiA+PgplbmRvYmoK
+ NTggMCBvYmoKWyA2NjcgNjExIDAgMCAwIDAgMCAwIDgzMyAwIDAgMCAwIDAgMCAwIDcy
+ MiA2NjcgMCAwIDAgMCAwIDAgMCAwIDAgMCA1NTYgMAo1MDAgNTU2IDU1NiAwIDU1NiA1
+ NTYgMjIyIDAgMCAyMjIgODMzIDU1NiA1NTYgNTU2IDAgMzMzIDUwMCAyNzggNTU2IDAg
+ MCA1MDAKXQplbmRvYmoKMjAgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1Ry
+ dWVUeXBlIC9CYXNlRm9udCAvWFlVVFBTK0hlbHZldGljYSAvRm9udERlc2NyaXB0b3IK
+ NTcgMCBSIC9XaWR0aHMgNTggMCBSIC9GaXJzdENoYXIgNjkgL0xhc3RDaGFyIDEyMCAv
+ RW5jb2RpbmcgL01hY1JvbWFuRW5jb2RpbmcKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1Rp
+ dGxlIChVbnRpdGxlZCkgL0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpIC9DcmVhdG9yIChP
+ bW5pR3JhZmZsZSkgL1Byb2R1Y2VyCihNYWMgT1MgWCAxMC41LjggUXVhcnR6IFBERkNv
+ bnRleHQpIC9DcmVhdGlvbkRhdGUgKEQ6MjAwOTA5MTExNDQwMzFaMDAnMDAnKQovTW9k
+ RGF0ZSAoRDoyMDA5MDkxMTE0NDAzMVowMCcwMCcpID4+CmVuZG9iagp4cmVmCjAgNTkK
+ MDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDQ5MjUyIDAwMDAwIG4gCjAwMDAwMDEwNDEg
+ MDAwMDAgbiAKMDAwMDAzNjY3MiAwMDAwMCBuIAowMDAwMDAwMDIyIDAwMDAwIG4gCjAw
+ MDAwMDEwMjIgMDAwMDAgbiAKMDAwMDAwMTE0NSAwMDAwMCBuIAowMDAwMDIxNzk2IDAw
+ MDAwIG4gCjAwMDAwMDUyMDQgMDAwMDAgbiAKMDAwMDAwNjEzMiAwMDAwMCBuIAowMDAw
+ MDAxMzY3IDAwMDAwIG4gCjAwMDAwMDIyODQgMDAwMDAgbiAKMDAwMDAwMjMwNCAwMDAw
+ MCBuIAowMDAwMDAzMTYxIDAwMDAwIG4gCjAwMDAwMDMxODEgMDAwMDAgbiAKMDAwMDAw
+ NDIyMCAwMDAwMCBuIAowMDAwMDA0MjQwIDAwMDAwIG4gCjAwMDAwMDUxODQgMDAwMDAg
+ biAKMDAwMDAzMTA0NSAwMDAwMCBuIAowMDAwMDQxNjkwIDAwMDAwIG4gCjAwMDAwNDkw
+ NzcgMDAwMDAgbiAKMDAwMDAzMDE4MCAwMDAwMCBuIAowMDAwMDA2MTUxIDAwMDAwIG4g
+ CjAwMDAwMDkwNDQgMDAwMDAgbiAKMDAwMDAyNzM4NSAwMDAwMCBuIAowMDAwMDE1MjI0
+ IDAwMDAwIG4gCjAwMDAwMTc5NTYgMDAwMDAgbiAKMDAwMDAyNDU5MCAwMDAwMCBuIAow
+ MDAwMDA5MDY1IDAwMDAwIG4gCjAwMDAwMTIyNDYgMDAwMDAgbiAKMDAwMDAzNjYzNSAw
+ MDAwMCBuIAowMDAwMDEyMjY3IDAwMDAwIG4gCjAwMDAwMTUyMDMgMDAwMDAgbiAKMDAw
+ MDAzMzg0MCAwMDAwMCBuIAowMDAwMDE3OTc3IDAwMDAwIG4gCjAwMDAwMjA4NjAgMDAw
+ MDAgbiAKMDAwMDAyMDg4MSAwMDAwMCBuIAowMDAwMDIxNzc2IDAwMDAwIG4gCjAwMDAw
+ MjE4MzIgMDAwMDAgbiAKMDAwMDAyNDU2OSAwMDAwMCBuIAowMDAwMDI0NjI3IDAwMDAw
+ IG4gCjAwMDAwMjczNjQgMDAwMDAgbiAKMDAwMDAyNzQyMiAwMDAwMCBuIAowMDAwMDMw
+ MTU5IDAwMDAwIG4gCjAwMDAwMzAyMTcgMDAwMDAgbiAKMDAwMDAzMTAyNSAwMDAwMCBu
+ IAowMDAwMDMxMDgyIDAwMDAwIG4gCjAwMDAwMzM4MTkgMDAwMDAgbiAKMDAwMDAzMzg3
+ NyAwMDAwMCBuIAowMDAwMDM2NjE0IDAwMDAwIG4gCjAwMDAwMzY3NTUgMDAwMDAgbiAK
+ MDAwMDAzNjgxOSAwMDAwMCBuIAowMDAwMDQxMjgwIDAwMDAwIG4gCjAwMDAwNDEzMDEg
+ MDAwMDAgbiAKMDAwMDA0MTUzNiAwMDAwMCBuIAowMDAwMDQxODczIDAwMDAwIG4gCjAw
+ MDAwNDg2NTIgMDAwMDAgbiAKMDAwMDA0ODY3MyAwMDAwMCBuIAowMDAwMDQ4OTA5IDAw
+ MDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgNTkgL1Jvb3QgNTAgMCBSIC9JbmZvIDEgMCBS
+ IC9JRCBbIDxmOTA3NjFiZGExNmY3ZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4KPGY5MDc2MWJk
+ YTE2ZjdlMmUwOTIyMDYyODdmZDhmMDNhPiBdID4+CnN0YXJ0eHJlZgo0OTQ2MAolJUVP
+ RgoxIDAgb2JqCjw8L0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpL0NyZWF0aW9uRGF0ZSAo
+ RDoyMDA5MDkxMTE0MTUwMFopL0NyZWF0b3IgKE9tbmlHcmFmZmxlIDUuMS4xKS9Nb2RE
+ YXRlIChEOjIwMDkwOTExMTQzODAwWikvUHJvZHVjZXIgKE1hYyBPUyBYIDEwLjUuOCBR
+ dWFydHogUERGQ29udGV4dCkvVGl0bGUgKFVudGl0bGVkKT4+CmVuZG9iagp4cmVmCjEg
+ MQowMDAwMDUwNzk4IDAwMDAwIG4gCnRyYWlsZXIKPDwvSUQgWzxmOTA3NjFiZGExNmY3
+ ZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4gPGY5MDc2MWJkYTE2ZjdlMmUwOTIyMDYyODdmZDhm
+ MDNhPl0gL0luZm8gMSAwIFIgL1ByZXYgNDk0NjAgL1Jvb3QgNTAgMCBSIC9TaXplIDU5
+ Pj4Kc3RhcnR4cmVmCjUwOTkzCiUlRU9GCg==
+
+ QuickLookThumbnail
+
+ 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
+ AdQB+wIkAk8CewKpAtkDCgM9A3IDqQPiBBwEWQSXBNcFGQVdBaIF6gYzBn4GywcaB2sH
+ vggTCGoIwwkdCXoJ2Qo5CpwLAQtnC9AMOgynDRYNhg35Dm4O5Q9eD9kQVhDVEVYR2RJe
+ EuYTbxP7FIkVGRWqFj8W1RdtGAgYpBlDGeQahxssG9Qcfh0pHdcehx86H+4gpSFeIhki
+ 1yOWJFglHCXjJqsndihDKRIp5Cq3K44sZi1ALh0u/C/eMMExpzKQM3o0ZzVWNkg3PDgy
+ OSo6JTsiPCE9Iz4nPy5ANkFBQk9DX0RxRYVGnEe1SNFJ70sPTDJNV05/T6lQ1VIEUzVU
+ aFWeVtdYEVlOWo5b0F0UXltfpGDwYj5jj2TiZjdnj2jpakZrpW0Hbmtv0nE7cqd0FXWF
+ dvh4bnnme2B83X5df9+BY4LqhHOF/4eOiR+KsoxIjeGPfJEZkrmUXJYBl6mZU5sAnK+e
+ YaAVocyjhqVCpwGowqqFrEyuFa/gsa6zf7VStyi5ALrbvLi+mMB7wmDESMYyyCDKD8wB
+ zfbP7tHo0+XV5Nfm2erb8d374AjiF+Qo5j3oVOpt7InuqPDK8u71Ffc++Wr7mf3K//9j
+ dXJ2AAAAAAAAAQAAAAAAAAEAAwAHAAsAEQAYACAAKQA0AEEATgBdAG4AgACUAKkAwADY
+ APIBDQEqAUkBaQGLAa8B1AH7AiQCTwJ7AqkC2QMKAz0DcgOpA+IEHARZBJcE1wUZBV0F
+ ogXqBjMGfgbLBxoHawe+CBMIagjDCR0JegnZCjkKnAsBC2cL0Aw6DKcNFg2GDfkObg7l
+ D14P2RBWENURVhHZEl4S5hNvE/sUiRUZFaoWPxbVF20YCBikGUMZ5BqHGywb1Bx+HSkd
+ 1x6HHzof7iClIV4iGSLXI5YkWCUcJeMmqyd2KEMpEinkKrcrjixmLUAuHS78L94wwTGn
+ MpAzejRnNVY2SDc8ODI5KjolOyI8IT0jPic/LkA2QUFCT0NfRHFFhUacR7VI0UnvSw9M
+ Mk1XTn9PqVDVUgRTNVRoVZ5W11gRWU5ajlvQXRReW1+kYPBiPmOPZOJmN2ePaOlqRmul
+ bQdua2/ScTtyp3QVdYV2+HhueeZ7YHzdfl1/34FjguqEc4X/h46JH4qyjEiN4Y98kRmS
+ uZRclgGXqZlTmwCcr55hoBWhzKOGpUKnAajCqoWsTK4Vr+CxrrN/tVK3KLkAutu8uL6Y
+ wHvCYMRIxjLIIMoPzAHN9s/u0ejT5dXk1+bZ6tvx3fvgCOIX5CjmPehU6m3sie6o8Mry
+ 7vUV9z75avuZ/cr//2N1cnYAAAAAAAABAAAAAAAAAQADAAcACwARABgAIAApADQAQQBO
+ AF0AbgCAAJQAqQDAANgA8gENASoBSQFpAYsBrwHUAfsCJAJPAnsCqQLZAwoDPQNyA6kD
+ 4gQcBFkElwTXBRkFXQWiBeoGMwZ+BssHGgdrB74IEwhqCMMJHQl6CdkKOQqcCwELZwvQ
+ DDoMpw0WDYYN+Q5uDuUPXg/ZEFYQ1RFWEdkSXhLmE28T+xSJFRkVqhY/FtUXbRgIGKQZ
+ QxnkGocbLBvUHH4dKR3XHocfOh/uIKUhXiIZItcjliRYJRwl4yarJ3YoQykSKeQqtyuO
+ LGYtQC4dLvwv3jDBMacykDN6NGc1VjZINzw4MjkqOiU7IjwhPSM+Jz8uQDZBQUJPQ19E
+ cUWFRpxHtUjRSe9LD0wyTVdOf0+pUNVSBFM1VGhVnlbXWBFZTlqOW9BdFF5bX6Rg8GI+
+ Y49k4mY3Z49o6WpGa6VtB25rb9JxO3KndBV1hXb4eG555ntgfN1+XX/fgWOC6oRzhf+H
+ jokfirKMSI3hj3yRGZK5lFyWAZepmVObAJyvnmGgFaHMo4alQqcBqMKqhaxMrhWv4LGu
+ s3+1UrcouQC627y4vpjAe8JgxEjGMsggyg/MAc32z+7R6NPl1eTX5tnq2/Hd++AI4hfk
+ KOY96FTqbeyJ7qjwyvLu9RX3Pvlq+5n9yv//WFlaIAAAAAAAAPbVAAEAAAAA0ytYWVog
+ AAAAAAAAAHoAAAB+AAAAaG1sdWMAAAAAAAAAAQAAAAxlblVTAAAAagAAABwAQwBvAHAA
+ eQByAGkAZwBoAHQAIAAoAGMAKQAgAFgALQBSAGkAdABlACwAIAAyADAAMAAxAC0AMgAw
+ ADAANwAuACAAQQBsAGwAIABSAGkAZwBoAHQAcwAgAFIAZQBzAGUAcgB2AGUAZAAuAAB2
+ Y2d0AAAAAAAAAAAAAwEAAAIAAAFtAtkERgWyBx8Iiwn4C2QM0Q49D6oRFhKDE+8VXBZh
+ F2cYbBlyGncbfRyCHYgejR+TIJkhniKkI6kkryWWJn0nZShMKTMqGysCK+ks0S24Lp8v
+ hzBuMVUyPTMmNBA0+jXjNs03tzigOYo6cztdPEc9MD4aPwQ/7UDsQetC6UPoROdF5Ubk
+ R+JI4UngSt5L3UzcTdpO2U/qUPpSC1McVCxVPVZOV15Yb1mAWpBboVyyXcJe01/gYOxh
+ +WMFZBJlHmYrZzdoRGlQal1ramx2bYNuj2+lcLtx0XLmc/x1EnYodz54U3lpen97lXyr
+ fcB+1n/SgM+By4LHg8OEwIW8hriHtIiwia2KqYuljKGNno6Cj2aQSpEvkhOS95PclMCV
+ pJaJl22YUZk1mhqa/pvcnLqdl551n1OgMKEOoeyiyqOnpIWlY6ZBpx6n/Kjdqb2qnat+
+ rF6tP64frv+v4LDAsaGygbNitEK1IrYCtuG3wLifuX66Xbs8vBu8+r3Zvri/l8B2wVbC
+ NcMHw9nErMV+xlDHI8f1yMfJmcpsyz7MEMzjzbXOh89E0ALQv9F80jnS9tOz1HDVLdXq
+ 1qfXZdgi2N/ZnNpP2wHbtNxn3Rrdzd6A3zLf5eCY4Uvh/uKw42PkFuS+5WbmDea1513o
+ BOis6VTp/Oqj60vr8+ya7ULt6gAAAS4CWwOJBLcF5AcSCEAJbQqbC8kM9g4kD1IQgBGt
+ EogTYxQ+FRkV9BbOF6kYhBlfGjobFRvwHMsdpR6AHxsftiBRIOwhhyIiIr0jWCPzJI4l
+ KSXEJl8m+ieVKEIo8CmdKksq+CumLFMtAS2uLlsvCS+2MGQxETG/MnIzJTPYNIs1PjXy
+ NqU3WDgLOL45cTokOtg7izw+PQQ9yT6PP1VAG0DhQadCbEMyQ/hEvkWERklHD0fVSLBJ
+ ikplSz9MGkz1Tc9Oqk+EUF9ROVIUUu9TyVSkVY1Wd1dgWElZM1ocWwZb71zZXcJerF+V
+ YH5haGJRYylkAWTZZbBmiGdgaDhpD2nnar9rl2xvbUZuHm72b8JwjnFZciVy8XO9dIl1
+ VHYgdux3uHiEeU96G3rne8l8rH2OfnB/U4A1gReB+oLcg76EoYWDhmWHSIgqiN+JlYpK
+ iwCLtYxrjSCN1o6Lj0GP9pCskWGSF5LMk4uUSpUIlceWhpdEmAOYwpmAmj+a/pu8nHud
+ Op34nrOfbaAnoOGhnKJWoxCjyqSFpT+l+aazp26oKKjiqYqqM6rbq4OsK6zUrXyuJK7N
+ r3WwHbDFsW6yFrK+s2u0F7TEtXC2HbbJt3a4IrjPuXu6KLrUu4G8LbzavYu+Pb7vv6DA
+ UsEDwbXCZsMYw8nEe8Usxd7Gj8dBAAABPAJ4A7QE8AYsB2gIpAngCxwMWA2UDtAQDBFI
+ EoQTZxRJFSwWDhbxF9MYthmYGnsbXhxAHSMeBR7oH8ogeCEmIdMigSMvI9wkiiU4JeYm
+ kydBJ+8onClKKfgqqCtYLAgsuS1pLhkuyS95MCkw2jGKMjoy6jOaNEo1DjXRNpU3WDgc
+ ON85ozpmOyo77TyxPXQ+Nz77P75AmEFxQktDJEP+RNdFsUaKR2RIPUkXSfBKykujTH1N
+ c05pT2BQVlFNUkNTOlQwVSdWHVcTWApZAFn3Wu1b21zIXbZepF+RYH9hbWJaY0hkNmUj
+ ZhFm/2fsaNpp0mrLa8RsvG21bq5vpnCfcZhykHOJdIJ1enZzd2x4bHltem57b3xvfXB+
+ cX9ygHKBc4J0g3SEdYV2hneHXYhDiSmKD4r1i9uMwY2njo2Pc5BZkT+SJZMLk/GU1ZW6
+ lp6Xg5hnmUuaMJsUm/mc3Z3CnqafiqBvoVOiR6M6pC2lIKYUpwen+qjtqeGq1KvHrLut
+ rq6hr5SwmbGfsqSzqbSutbO2uLe9uMK5x7rNu9K8173cvuG//MEXwjPDTsRpxYTGn8e7
+ yNbJ8csMzCfNQ85ez3nQm9G90t/UAdUj1kbXaNiK2azaztvw3RLeNN9W4HjikuSs5sbo
+ 4Or67RTvL/FJ82P1ffeX+bH7y/3l//8AAHNmMzIAAAAAAAEN+QAAB+QAAAIBAAAMYwAA
+ 9SH////2AAABX////RUAARx2
+
+ ReadOnly
+ NO
+ RowAlign
+ 1
+ RowSpacing
+ 36
+ SheetTitle
+ Canvas 1
+ SmartAlignmentGuidesActive
+ YES
+ SmartDistanceGuidesActive
+ YES
+ UniqueID
+ 1
+ UseEntirePage
+
+ VPages
+ 1
+ WindowInfo
+
+ CurrentSheet
+ 0
+ ExpandedCanvases
+
+
+ name
+ Canvas 1
+
+
+ Frame
+ {{218, 52}, {999, 826}}
+ ListView
+
+ OutlineWidth
+ 142
+ RightSidebar
+
+ ShowRuler
+
+ Sidebar
+
+ SidebarWidth
+ 120
+ VisibleRegion
+ {{-54, -59}, {864, 672}}
+ Zoom
+ 1
+ ZoomValues
+
+
+ Canvas 1
+ 1
+ 1
+
+
+
+ saveQuickLookFiles
+ YES
+
+
diff --git a/truman/src/docs/asciidoc/images/oxm-exceptions.png b/truman/src/docs/asciidoc/images/oxm-exceptions.png
new file mode 100644
index 000000000000..8515e7c4887a
Binary files /dev/null and b/truman/src/docs/asciidoc/images/oxm-exceptions.png differ
diff --git a/truman/src/docs/asciidoc/images/phantom-read-process.png b/truman/src/docs/asciidoc/images/phantom-read-process.png
new file mode 100644
index 000000000000..f0db67bf262f
Binary files /dev/null and b/truman/src/docs/asciidoc/images/phantom-read-process.png differ
diff --git a/truman/src/docs/asciidoc/images/problem-reads.png b/truman/src/docs/asciidoc/images/problem-reads.png
new file mode 100644
index 000000000000..2fd072e34ed9
Binary files /dev/null and b/truman/src/docs/asciidoc/images/problem-reads.png differ
diff --git a/truman/src/docs/asciidoc/images/prototype.png b/truman/src/docs/asciidoc/images/prototype.png
new file mode 100644
index 000000000000..26fa2c1cf2d9
Binary files /dev/null and b/truman/src/docs/asciidoc/images/prototype.png differ
diff --git a/truman/src/docs/asciidoc/images/relationships-between-classes.png b/truman/src/docs/asciidoc/images/relationships-between-classes.png
new file mode 100644
index 000000000000..e478526a1bfb
Binary files /dev/null and b/truman/src/docs/asciidoc/images/relationships-between-classes.png differ
diff --git a/truman/src/docs/asciidoc/images/second-lost-update-process.png b/truman/src/docs/asciidoc/images/second-lost-update-process.png
new file mode 100644
index 000000000000..f6c39c0efd44
Binary files /dev/null and b/truman/src/docs/asciidoc/images/second-lost-update-process.png differ
diff --git a/truman/src/docs/asciidoc/images/setting-gradle-test-runner.png b/truman/src/docs/asciidoc/images/setting-gradle-test-runner.png
new file mode 100644
index 000000000000..15df36f9d8d9
Binary files /dev/null and b/truman/src/docs/asciidoc/images/setting-gradle-test-runner.png differ
diff --git a/truman/src/docs/asciidoc/images/singleton.png b/truman/src/docs/asciidoc/images/singleton.png
new file mode 100644
index 000000000000..591520ec1dcc
Binary files /dev/null and b/truman/src/docs/asciidoc/images/singleton.png differ
diff --git a/truman/src/docs/asciidoc/images/spring-and-mybatis.jpg b/truman/src/docs/asciidoc/images/spring-and-mybatis.jpg
new file mode 100644
index 000000000000..c1442b430011
Binary files /dev/null and b/truman/src/docs/asciidoc/images/spring-and-mybatis.jpg differ
diff --git a/truman/src/docs/asciidoc/images/spring-aop-process.png b/truman/src/docs/asciidoc/images/spring-aop-process.png
new file mode 100644
index 000000000000..61baaebd92cb
Binary files /dev/null and b/truman/src/docs/asciidoc/images/spring-aop-process.png differ
diff --git a/truman/src/docs/asciidoc/images/spring-bean-lifecycle.svg b/truman/src/docs/asciidoc/images/spring-bean-lifecycle.svg
new file mode 100644
index 000000000000..4003367e7af5
--- /dev/null
+++ b/truman/src/docs/asciidoc/images/spring-bean-lifecycle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/truman/src/docs/asciidoc/images/spring-logo.jpg b/truman/src/docs/asciidoc/images/spring-logo.jpg
new file mode 100644
index 000000000000..bf25598fcbb8
Binary files /dev/null and b/truman/src/docs/asciidoc/images/spring-logo.jpg differ
diff --git a/truman/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png b/truman/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png
new file mode 100644
index 000000000000..6e0eeab744d4
Binary files /dev/null and b/truman/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png differ
diff --git a/truman/src/docs/asciidoc/images/spring-overview.png b/truman/src/docs/asciidoc/images/spring-overview.png
new file mode 100644
index 000000000000..952c9db6c86f
Binary files /dev/null and b/truman/src/docs/asciidoc/images/spring-overview.png differ
diff --git a/truman/src/docs/asciidoc/images/stack-frame.png b/truman/src/docs/asciidoc/images/stack-frame.png
new file mode 100644
index 000000000000..18b317205151
Binary files /dev/null and b/truman/src/docs/asciidoc/images/stack-frame.png differ
diff --git a/truman/src/docs/asciidoc/images/transactional-summary.png b/truman/src/docs/asciidoc/images/transactional-summary.png
new file mode 100644
index 000000000000..2083435b4eb8
Binary files /dev/null and b/truman/src/docs/asciidoc/images/transactional-summary.png differ
diff --git a/truman/src/docs/asciidoc/images/tx.png b/truman/src/docs/asciidoc/images/tx.png
new file mode 100644
index 000000000000..06f2e77c76f8
Binary files /dev/null and b/truman/src/docs/asciidoc/images/tx.png differ
diff --git a/truman/src/docs/asciidoc/images/tx_prop_required.png b/truman/src/docs/asciidoc/images/tx_prop_required.png
new file mode 100644
index 000000000000..218790aca635
Binary files /dev/null and b/truman/src/docs/asciidoc/images/tx_prop_required.png differ
diff --git a/truman/src/docs/asciidoc/images/tx_prop_requires_new.png b/truman/src/docs/asciidoc/images/tx_prop_requires_new.png
new file mode 100644
index 000000000000..a8ece48193f3
Binary files /dev/null and b/truman/src/docs/asciidoc/images/tx_prop_requires_new.png differ
diff --git a/truman/src/docs/asciidoc/images/wx-jikerizhi.png b/truman/src/docs/asciidoc/images/wx-jikerizhi.png
new file mode 100644
index 000000000000..9653b7e4252e
Binary files /dev/null and b/truman/src/docs/asciidoc/images/wx-jikerizhi.png differ
diff --git a/truman/src/docs/asciidoc/images/wxpay.jpg b/truman/src/docs/asciidoc/images/wxpay.jpg
new file mode 100644
index 000000000000..1697d263d10a
Binary files /dev/null and b/truman/src/docs/asciidoc/images/wxpay.jpg differ
diff --git a/truman/src/docs/asciidoc/images/wxpay.png b/truman/src/docs/asciidoc/images/wxpay.png
new file mode 100644
index 000000000000..8b848b5a5449
Binary files /dev/null and b/truman/src/docs/asciidoc/images/wxpay.png differ
diff --git a/truman/src/docs/asciidoc/import-into-eclipse.adoc b/truman/src/docs/asciidoc/import-into-eclipse.adoc
new file mode 100644
index 000000000000..598df5e44962
--- /dev/null
+++ b/truman/src/docs/asciidoc/import-into-eclipse.adoc
@@ -0,0 +1,4 @@
+[#import-into-eclipse]
+= 将 Spring 导入到 Eclipse 中
+
+在 Mac OSX 、 Ubuntu 上执行 `SPRING_HOME/import-into-eclipse.sh`;在 Windows 上 `{var_spring_home}/import-into-eclipse.bat`,并参考相关的输出内容来导入到 Eclipse 中。
diff --git a/truman/src/docs/asciidoc/import-into-idea.adoc b/truman/src/docs/asciidoc/import-into-idea.adoc
new file mode 100644
index 000000000000..22faf4659f0a
--- /dev/null
+++ b/truman/src/docs/asciidoc/import-into-idea.adoc
@@ -0,0 +1,64 @@
+[#import-into-idea]
+= 将 Spring 导入到 IntelliJ IDEA
+
+古语有云:“工欲善其事,必先利其器!”尤其是 Java 平台,对调试的支持堪称完美,相关的工具又
+是很好很强大。做 Spring 源码分析,也必须有得心应手的工具相辅相成才能事半功倍。
+
+在 Java 开发领域中,众所周知的集成开发工具有三种:Eclipse、IDEA、Netbeans。D瓜哥在工作中,自己用过
+Eclipse、IDEA。平时见到的开发工具也是以这两款为主。所以,重点介绍一下 Spring 如何导入
+到这两款工具,以及如何在其中运行相关代码。本节介绍如何导入到 IDEA。
+
+== 正常导入
+
+在 Spring 的版本库中,也有相关文档来介绍如何导入到 IDEA。我们先按照这个文档来进行操作一
+遍:
+
+. 在终端(Windows 系统上,推荐使用 Cmder)中,进入到 Spring 源码根目录 `SPRING_HOME`。
+. 预编译 `spring-oxm` 模块: `./gradlew cleanIdea :spring-oxm:compileTestJava`;在
+Windows 系统上,请执行 `gradlew cleanIdea :spring-oxm:compileTestJava`。
+. 导入到 IDEA 中:File → New → Project from Existing Sources... → 选中 Spring 源码
+目录 → OK → import from external model → Gradle → Next → Finish,然后经过漫长的等待
+后就成功导入到 IDEA 中了。
+. 设计 Project 的 JDK 版本。这里分析 Spring {spring-version},要求 JDK 的版本最低为 JDK 8。
+. 官方文档上显示,需要排除 `spring-aspects`,但是根据D瓜哥自己的运行测试情况来看,没有
+发现什么问题,这里就不再排除。
+
+按照文档来操作,可以顺利导入,但是在导入过程以及运行单元测试代码时会遇到一些问题。接下来,
+D瓜哥介绍一下如何解决这些问题。
+
+== 加快 Gradle 下载速度
+
+遇到的第一个问题:在执行 *预编译 `spring-oxm` 模块* 时,耗时特别长。只是一味地打印出一些点点,不确定是否出现什么问题。
+
+这是由于在首次执行命令时,相当于执行 Gradle 任务,这需要下载构建工具 Gradle。由于国内特殊的网络问题,有些地方下载得很慢,有些地方甚至根本下载不了。
+
+其实,解决这个问题也很简单,基本思路是这样的:在 `SPRING_HOME/gradle/wrapper/gradle-wrapper.properties` 文件中的 `distributionUrl` 属性指明了所需的 Gradle 下载路径。初次执行 Gradle 命令时,需要下载对应版本的 Gradle。下载中 Gradle 会存放在 `GRADLE_USER_HOME/wrapper/dists/` 的子目录下,Gradle 会在该目录下创建一个对应的目录(该目录不固定,中间有一段是一个自动生成的字符串。)。直接复制下来 `distributionUrl` 对应的下载链接,通过迅雷下载完成后,将 Gradle 压缩包复制到上述目录下,借此来“欺骗” Gradle,让其以为是自己下载完成的。终止运行的任务,然后再次执行 `./gradlew cleanIdea :spring-oxm:compileTestJava`,你会发现,很快就能完成。
+
+== 自动手动建立 Gradle 执行任务。
+
+上面的问题还好,即使不 Hack 一下,慢慢等待也能顺利完成。但是,把 Spring 导入到 IDEA 后,
+分析 Spring 源代码,运行单元测试,进行单步调试,这是基本要求了。但是,在 IDEA 15.02以后
+的版本中运行时,你就会发现,依赖的各种库都需要下载,典型的如 JUnit、Apache Commons Loggings。
+实际这些库在导入时,都已经下载好了。你可以在 `USER_HOME/.gradle/caches/modules-2/files-2.1`
+(可能后面的数字会有变化)目录中找到相应的库。但是,为什么 IDEA 却找不到呢?
+
+其实,这是由于单元测试代码的运行方式导致的。在 IDEA 15.02 以后,运行单元测试时,默认使用
+的是 *Platform Test Runner*。可以通过手动建立 Gradle 方式的测试运行配置来解决这个问题。
+如下图:
+
+image::images/manual-new-test.png[title="手动建测试运行配置", {image_attr}]
+
+上图中建立的整个测试类的运行配置。如果只想运行单个测试方法,只需要修改一下
+*Script parameters*。将其修改为: `--tests "org.springframework.beans.factory.DefaultListableBeanFactoryTests.testUnreferencedSingletonWasInstantiated"`
+即可。
+
+新建完成后,就可以点击运行或者调试按钮来进行测试了。
+
+== 使用 Gradle 方式来运行单元测试
+
+上面的方式治标不治本,而且相当麻烦。更简单也更根本的解决办法是将默认 *Test Runner* 修改
+为 *Gradle Test Runner*。截图如下:
+
+image::images/setting-gradle-test-runner.png[title="设置 Test Runner", {image_attr}]
+
+经过上面的设置后,所有的单元测试都可以顺利执行了。
diff --git a/truman/src/docs/asciidoc/index.adoc b/truman/src/docs/asciidoc/index.adoc
new file mode 100644
index 000000000000..d24dbfa1cc5f
--- /dev/null
+++ b/truman/src/docs/asciidoc/index.adoc
@@ -0,0 +1,34 @@
+= Spring 源码分析^Alpha^
+include::{includedir}/_attributes.adoc[]
+
+:!sectnums:
+
+include::{includedir}/preface.adoc[leveloffset=+1]
+
+include::{includedir}/questions.adoc[leveloffset=+1]
+
+:sectnums:
+
+include::{includedir}/development-environment.adoc[leveloffset=+1]
+
+include::{includedir}/architecture.adoc[leveloffset=+1]
+
+include::{includedir}/ioc.adoc[leveloffset=+1]
+
+include::{includedir}/aop.adoc[leveloffset=+1]
+
+include::{includedir}/data-access.adoc[leveloffset=+1]
++
+include::{includedir}/mvc.adoc[leveloffset=+1]
+
+include::{includedir}/extensions-and-dubbo.adoc[leveloffset=+1]
+
+include::{includedir}/tips.adoc[leveloffset=+1]
+
+include::{includedir}/uml.adoc[leveloffset=+1]
+
+include::{includedir}/tools.adoc[leveloffset=+1]
+
+include::{includedir}/xmls.adoc[leveloffset=+1]
+
+include::{includedir}/references.adoc[leveloffset=+1]
\ No newline at end of file
diff --git a/truman/src/docs/asciidoc/inject-static-field.adoc b/truman/src/docs/asciidoc/inject-static-field.adoc
new file mode 100644
index 000000000000..3a6ec6870ad0
--- /dev/null
+++ b/truman/src/docs/asciidoc/inject-static-field.adoc
@@ -0,0 +1,26 @@
+[#inject-static-field]
+= 注入静态属性
+
+[source,xml,{source_attr}]
+----
+
+
+
+
+
+
+
+
+----
+
+[source,java,{source_attr}]
+----
+public class SessionUtil {
+
+ private static LocationService locationService;
+
+ public static void setLocationService(LocationService ls) {
+ locationService = ls;
+ }
+}
+----
diff --git a/truman/src/docs/asciidoc/install-git.adoc b/truman/src/docs/asciidoc/install-git.adoc
new file mode 100644
index 000000000000..ad4430969d6b
--- /dev/null
+++ b/truman/src/docs/asciidoc/install-git.adoc
@@ -0,0 +1,60 @@
+[#install-git]
+= 安装 Git
+
+由于 Spring 的源代码是使用 Git 来做版本管理的,而且是托管在 https://github.com/[Github^] 上。所以,需要先安装相应的版本管理工具 Git。本节D瓜哥就来介绍一下 Git 的安装。
+
+[#install-git-on-mac]
+== 在 Mac OSX 上安装 Git
+
+在 Mac OSX 系统上安装 Git 非常简单。只需一条命令即可:
+
+[source,bash,{source_attr}]
+----
+brew insatll git
+----
+
+NOTE: 没有使用过 Homebrew,请参考 https://brew.sh/index_zh-cn.html[Homebrew — OS X 不可或缺的套件管理器^]。
+
+[#install-git-on-win]
+== 在 Windows 上安装 Git
+
+在 Windows 上安装 Git,也比较简单了,直接去 https://gitforwindows.org/[Git for Windows^] 下载最新版,然后下一步下一步就OK了。
+
+NOTE: 由于国内的特殊网络状况,有可能下载可能会很慢甚至失败。实在不行,请“科学上网”。
+
+[#install-git-on-linux]
+== 在 Ubuntu 上安装 Git
+
+在 Ubuntu 上安装 Git,相对来说,稍微麻烦一点点,需要多执行几个命令。命令如下:
+
+[source,bash,{source_attr}]
+----
+sudo apt-add-repository ppa:git-core/ppa # <1>
+sudo apt-get update # <2>
+sudo apt-get install git # <3>
+----
+<1> 这是添加 Git 的软件源;
+<2> 更新软件源,这样可以应用上第一步安装的软件源,并且可以安装到最新版;
+<3> 安装 Git。
+
+[NOTE]
+====
+如果在执行第一步时,提示找不到命令时,请执行 `sudo apt-get install -y python-software-properties`。
+
+`add-apt-repository` 命令可以向本地软件源中添加PPA软件库提供的软件地址,然后就可以使用 `apt-get` 更新安装、更新软件。而 `add-apt-repository` 是由 `python-software-properties` 这个工具包提供的。所以要先安装 `python-software-properties` 就能使用 `add-apt-repository`。
+====
+
+[#config-git]
+== 配置 Git
+
+经过上一节的内容后,Git 已经安装好了。但是,在使用之前,需要做一些简单的配置。Mac OSX、Ubuntu 上直接打开终端,在 Windows 上打开刚刚安装的 *Git Bash*,然后执行如下命令:
+
+[source,bash,{source_attr}]
+----
+git config --global user.name # <1>
+git config --global user.email # <2>
+----
+<1> 配置用户名;
+<2> 配置电子邮箱。
+
+然后,就可以正常使用了。由于 Git 不是本书的重点。这里就不做过多介绍了。等后续用到再视情况来介绍。
diff --git a/truman/src/docs/asciidoc/ioc.adoc b/truman/src/docs/asciidoc/ioc.adoc
new file mode 100644
index 000000000000..5592222cdbd8
--- /dev/null
+++ b/truman/src/docs/asciidoc/ioc.adoc
@@ -0,0 +1,163 @@
+[#ioc]
+= IoC 的实现原理
+
+TODO: 感觉可以通过向 `ClassPathScanningCandidateComponentProvider` 中添加过滤注解来实现扩展功能。抽空尝试一下。
+
+TODO: 除了 singleton 和 prototype 外,其他 Scope 类型的 Bean 实例是怎么缓存的?
+
+TODO: `default-autowire="byName"` 等实现自动装配的功能在哪里实现的?怎么实现的?是否会遍历 Bean 的所有属性? `org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean` 中有相关类似实现。
+
+autowiring 的实现过程:
+
+. 对 Bean 的属性代调用 getBean()方法,完成依赖 Bean 的初始化和依赖注入。
+. 将依赖 Bean 的属性引用设置到被依赖的 Bean 属性上。
+. 将依赖 Bean 的名称和被依赖 Bean 的名称存储在 IOC 容器的集合中。
+
+对属性的注入过程分以下两种情况:
+
+. 属性值类型不需要强制转换时,不需要解析属性值,直接准备进行依赖注入。
+. 属性值需要进行类型强制转换时,如对其他对象的引用等,首先需要解析属性值,然后对解析后的属性值进行依赖注入。
+
+
+Spring IoC 容器是如何将属性的值注入到 Bean 实例对象中去的:
+
+. 对于集合类型的属性,将其属性值解析为目标类型的集合后直接赋值给属性。
+. 对于非集合类型的属性,大量使用了 JDK 的反射机制,通过属性的 Getter 方法获取指定属性注入以前的值,同时调用属性的 Setter 方法为属性设置注入后的值。
+
+从 `ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod` 可以看出,对 `@Bean` 的处理复用了自定义 `factory-method` 的处理。在 `spring-beans.xsd` 文件中,可以找到对 `factory-method` 属性的说明。
+
+include::{includedir}/bean-definition.adoc[leveloffset=+1]
+
+include::{includedir}/bean-factory.adoc[leveloffset=+1]
+
+include::{includedir}/factory-bean.adoc[leveloffset=+1]
+
+include::{includedir}/environment.adoc[leveloffset=+1]
+
+include::{includedir}/application-context.adoc[leveloffset=+1]
+
+include::{includedir}/startup-process-overview.adoc[leveloffset=+1]
+
+include::{includedir}/bean-lifecycle-overview.adoc[leveloffset=+1]
+
+include::{includedir}/extensions-overview.adoc[leveloffset=+1]
+
+include::{includedir}/circular-dependence.adoc[leveloffset=+1]
+
+== I18n
+
+properties 文件内容是以 ISO-8859-1 编码的。所以,不支持中文,需要把中文进行转码。
+
+plantuml::{includedir}/puml/MessageSource.puml[{diagram_attr}]
+
+== 事件发布
+
+plantuml::{includedir}/puml/ApplicationEvent.puml[{diagram_attr}]
+
+容器启动伊始,就会检查容器内是否存在名称为 `applicationEventMulticaster` 的 `ApplicationEventMulticaster` 对象实例。有的话就使用提供的实现,没有则默认初始化一个 `SimpleApplicationEventMulticaster` 作为将会使用的 `ApplicationEventMulticaster`。
+
+在 `refresh()` 时,先调用 `initMessageSource()` 初始化 `MessageSource` 实例;然后调用 `initApplicationEventMulticaster()` 初始化 `ApplicationEventMulticaster`。
+
+Spring 是以 Bean 为核心的。Bean 的配置、配置的读取和解析、以合适的数据结构对 Bean 元数据进行各种操作等。
+
+Spring 是如何解决构造函数依赖的呢?以及如何注入呢?
+
+== 内置 `PostProcessor` 的注册
+
+在 `AnnotationConfigUtils.registerAnnotationConfigProcessors(BeanDefinitionRegistry)` 方法中,注册了 Spring 内置的一些核心 `PostProcessor`:
+
+. `ConfigurationClassPostProcessor`
+. `AutowiredAnnotationBeanPostProcessor`
+. `CommonAnnotationBeanPostProcessor`
+. `PersistenceAnnotationBeanPostProcessor`? -- 这个得看是否需要
+. `EventListenerMethodProcessor`
+. `DefaultEventListenerFactory`
+
+通过对 `AnnotationConfigUtils.registerAnnotationConfigProcessors` 调用追踪来看,在如下地方进行了调用:
+
+. 通过 `AnnotationConfigBeanDefinitionParser.parse` 在处理 `` 时;
+. 通过 `ComponentScanBeanDefinitionParser.parse` 在处理 `` 时;
+. 通过 `AnnotatedBeanDefinitionReader` 构造函数在初始化时;
+. 通过 `ClassPathBeanDefinitionScanner.scan` 在扫描类路径时;
+
+覆盖了 XML 配置文件和注解配置两种最核心的场景。
+
+
+plantuml::{includedir}/puml/BeanDefinition.puml[{diagram_attr}]
+
+[#uml-BeanFactory]
+plantuml::{includedir}/puml/BeanFactory.puml[{diagram_attr}]
+
+plantuml::{includedir}/puml/ConfigurationClassPostProcessor.puml[{diagram_attr}]
+
+include::{includedir}/common-interfaces-introduction.adoc[leveloffset=+1]
+
+include::{includedir}/resource.adoc[leveloffset=+1]
+
+include::{includedir}/tag-resolve.adoc[leveloffset=+1]
+
+include::{includedir}/annotations-resolve.adoc[leveloffset=+1]
+
+可以使用 p-namespace 来简化属性的赋值操作:
+
+[{xml_src_attr}]
+----
+
+
+
+
+
+
+
+
+
+----
+
+可以使用 c-namespace 来简化构造函数参数的声明:
+
+[{xml_src_attr}]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+除了常规的 `@Autowired` 和 `@Resource` 注入外,还可以使用 `@Lookup` 注解来注入依赖。示例如下:
+
+[{java_src_attr}]
+----
+include::{truman_src_dir}/context/AnnoLookupTest.java[]
+----
+
+这里有个疑问:为什么要把 `@Lookup` 注解标注在抽象方法上?
+
+== `BeanNameGenerator` 自定义 Bean 名称
+
+如果想自定义 Bean 名称,可以实现 `BeanNameGenerator` 接口,然后将其配置到 Spring 容器上。更详细文档,请看: https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-scanning-name-generator[Core Technologies:Naming Autodetected Components^]。
+
+
+include::{includedir}/property-placeholder.adoc[leveloffset=+1]
\ No newline at end of file
diff --git a/truman/src/docs/asciidoc/jdbc.adoc b/truman/src/docs/asciidoc/jdbc.adoc
new file mode 100644
index 000000000000..b637a2c90085
--- /dev/null
+++ b/truman/src/docs/asciidoc/jdbc.adoc
@@ -0,0 +1,41 @@
+[#jdbc]
+= JdbcTemplate
+
+`SQLExceptionTranslator` 是一个接口,如果你需要在 `SQLException` 和 `org.springframework.dao.DataAccessException` 之间作转换,那么必须实现该接口。
+
+转换器类的实现可以采用一般通用的做法(比如使用 JDBC 的 SQLState code),如果为了使转换更准确,也可以进行定制(比如使用 Oracle 的 error code)。
+
+`SQLErrorCodeSQLExceptionTranslator` 是 `SQLExceptionTranslator` 的默认实现。该实现使用指定数据库厂商的 error code,比采用 SQLState 更精确。转换过程基于一个 JavaBean ( 类 型 为 SQLErrorCodes ) 中 的 error code 。
+
+这 个 JavaBean 由 `SQLErrorCodesFactory` 工厂类创建,其中的内容来自于 *`sql-error-codes.xml`* 配置文 件 。
+
+该文件中的数据库厂商代码基于 Database MetaData 信息中的 DatabaseProductName,从而配合当前数据库的使用。
+
+`SQLErrorCodeSQLExceptionTranslator` 使用以下的匹配规则:首先检查是否存在完成定制转换的子类实现 。通常 `SQLErrorCodeSQLExceptionTranslator` 这个类可以作为一个具体类使用,不需要进行定制,那么这个规则将不适用。
+接着将 `SQLException` 的 error code 与错误代码集中的 error code 进行匹配。默认情况下错误代码集将从 `SQLErrorCodesFactory` 取得。错误代码集来自 classpath 下的 `sql-error-codes.xml` 文件,它们将与数据库 metadata 信息中的 database name 进行映射。
+
+== 基于 `AbstractRoutingDataSource` 的主从切换
+
+可以考虑使用 `AbstractRoutingDataSource` 做一个透明主从切换代理:
+
+[{java_src_attr}]
+----
+include::{truman_src_dir}/jdbc/RoutingDataSourceTest.java[]
+----
+
+WARNING: 这还是一个半成品!如果用于生成,还需要打磨,比如简化配置和侵入、接入配置中心等。
+
+== 异常体系
+
+Spring 会根据错误码和 SQL 状态码将 `SQLExeption` 转换为对应的 Spring DAO 异常 。 在 `org.springframework.jdbc.support` 包中定义了 `SQLExceptionTranslator` 接口,该接口的两个实现类 `SQLErrorCodeSQLExceptionTranslator` 和 `SQLStateSQLExceptionTranslator` 分别负责处理 `SQLException` 中错误代码和 SQL 状态码的转换工作 。
+
+
+`SQLErrorCodeSQLExceptionTranslator.doTranslate` 是真正实现从错误码到异常的转换工作。在 `sql-error-codes.xml` 文件中定义异常类型,实现可扩展性。
+
+在两个地方完成异常转换工作:
+
+. 在执行 SQL 时报错,这个时候就要进行回滚。所以,在回滚时,执行异常转换。
++
+TODO dgg 如果"关闭事务"(事务是否可以关闭?)或只读事务时,有事务吗?会执行回滚吗?
++
+. 在提交时报错,进行异常转换。
diff --git a/truman/src/docs/asciidoc/jpa.adoc b/truman/src/docs/asciidoc/jpa.adoc
new file mode 100644
index 000000000000..d24ff10d0cda
--- /dev/null
+++ b/truman/src/docs/asciidoc/jpa.adoc
@@ -0,0 +1,2 @@
+[#jpa]
+= 整合 JPA
diff --git a/truman/src/docs/asciidoc/lifecycle-callback.adoc b/truman/src/docs/asciidoc/lifecycle-callback.adoc
new file mode 100644
index 000000000000..aa1edec62cbe
--- /dev/null
+++ b/truman/src/docs/asciidoc/lifecycle-callback.adoc
@@ -0,0 +1,9 @@
+[#lifecycle-callback]
+= 生命周期回调
+
+. `@PostConstruct`
+. `@PreDestroy`
+. `InitializingBean`
+. `DisposableBean`
+. `init-method`
+. `destroy-method`
diff --git a/truman/src/docs/asciidoc/mvc.adoc b/truman/src/docs/asciidoc/mvc.adoc
new file mode 100644
index 000000000000..0ce1b3adfd00
--- /dev/null
+++ b/truman/src/docs/asciidoc/mvc.adoc
@@ -0,0 +1,11 @@
+[#mvc]
+= Spring MVC
+
+通过 `org.springframework.web.servlet.HttpServletBean.init` 方法开始初始化容器的动作,再进一步委托给 `org.springframework.web.servlet.FrameworkServlet.initServletBean` 方法完成初始化容器。
+
+这个操作和 `org.springframework.web.context.ContextLoaderListener.contextInitialized` 启动 Spring 容器有什么区别?
+
+plantuml::{includedir}/puml/DispatcherServlet.puml[{diagram_attr}]
+
+
+plantuml::{includedir}/puml/DispatchServlet-init-sequence.puml[{diagram_attr}]
diff --git a/truman/src/docs/asciidoc/orm.adoc b/truman/src/docs/asciidoc/orm.adoc
new file mode 100644
index 000000000000..8249f78b97d7
--- /dev/null
+++ b/truman/src/docs/asciidoc/orm.adoc
@@ -0,0 +1,8 @@
+[#orm]
+= Spring 整合 ORM 框架
+
+include::{includedir}/hibernate.adoc[leveloffset=+1]
+
+include::{includedir}/jpa.adoc[leveloffset=+1]
+
+include::{includedir}/extensions-and-mybatis.adoc[leveloffset=+1]
diff --git a/truman/src/docs/asciidoc/performance-monitor.adoc b/truman/src/docs/asciidoc/performance-monitor.adoc
new file mode 100644
index 000000000000..3f68416b9c9b
--- /dev/null
+++ b/truman/src/docs/asciidoc/performance-monitor.adoc
@@ -0,0 +1,52 @@
+[#performance-monitor]
+= 性能监视器
+
+[source,xml,{source_attr}]
+.引入依赖
+----
+
+ com.jamonapi
+ jamon
+ 2.81
+
+----
+
+[source,xml,{source_attr}]
+.增加 Spring 配置
+----
+
+
+
+
+
+
+
+
+----
+
+[source,xml,{source_attr}]
+.增加日志配置
+----
+
+ /tmp/durian_performance.log
+
+
+ /tmp/durian_performance.%i.log.zip
+ 1
+ 2
+
+
+ 100MB
+
+
+
+ %date [%thread] %-5level %logger{72} - %msg%n
+
+
+
+
+
+
+----
+
+TIP: 注意 `JamonPerformanceMonitorInterceptor` 的日志级别。线上环境的输入级别一般是 `INFO` ,如果不配置,则这里的日志直接被过滤掉了。
diff --git a/truman/src/docs/asciidoc/preface.adoc b/truman/src/docs/asciidoc/preface.adoc
new file mode 100644
index 000000000000..0f53af68a306
--- /dev/null
+++ b/truman/src/docs/asciidoc/preface.adoc
@@ -0,0 +1,28 @@
+[preface]
+= 前言
+
+本文档是 D瓜哥 阅读 Spring 源码以及相关文档时的笔记。对学习内容做一些总结和提炼,分享出来也方便大家一起学习,共同进步。
+
+== 友情支持
+
+如果您觉得这个笔记对您有所帮助,看在D瓜哥码字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜
+
+[cols="2*^",frame=none]
+|===
+| image:images/alipay.png[title="支付宝", alt="支付宝", width="95%"]
+| image:images/wxpay.jpg[title="微信", alt="微信", width="95%"]
+|===
+
+有些打赏的朋友希望可以加个好友,欢迎关注D瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。
+
+image::images/wx-jikerizhi.png[{image_attr}]
+
+TIP: **公众号的微信号是: jikerizhi (“极客日志”全拼)**。__因为众所周知的原因,有时图片加载不出来。如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。__
+
+== 官网及版本库
+
+本文档的版本库托管在 Github 上,另外单独发布。
+
+“地瓜哥”博客网:: https://www.diguage.com/[^] 。D瓜哥的个人博客。欢迎光临,不过,内容很杂乱,请见谅。不见谅,你来打我啊,😂😂
+本文档官网:: https://diguage.github.io/spring-framework/[^] 。为了方便阅读,这里展示了处理好的文档。阅读请点击这个网址。
+本文档版本库:: https://github.com/diguage/spring-framework[^] 。由于组织方式的特殊性,坦白讲,不建议大家发 PR。有问题,欢迎发 Issue 讨论。
\ No newline at end of file
diff --git a/truman/src/docs/asciidoc/property-placeholder.adoc b/truman/src/docs/asciidoc/property-placeholder.adoc
new file mode 100644
index 000000000000..704f2c381a49
--- /dev/null
+++ b/truman/src/docs/asciidoc/property-placeholder.adoc
@@ -0,0 +1,25 @@
+= 占位符解析
+
+.`PropertyPlaceholderHelper.parseStringValue`
+[{java_src_attr}]
+----
+include::{core_src_dir}/util/PropertyPlaceholderHelper.java[tag=parseStringValue]
+----
+
+
+.`PropertyPlaceholderHelper.parseStringValue`
+[{java_src_attr}]
+----
+include::{core_src_dir}/util/PropertyPlaceholderHelper.java[tag=findPlaceholderEndIndex]
+----
+
+plantuml::{includedir}/puml/org.springframework.context.config.PropertyPlaceholderBeanDefinitionParser.puml[{diagram_attr}]
+
+plantuml::{includedir}/puml/org.springframework.context.config.PropertyPlaceholderBeanDefinitionParser-parse.puml[{diagram_attr}]
+
+plantuml::{includedir}/puml/org.springframework.context.support.PropertySourcesPlaceholderConfigurer.puml[{diagram_attr}]
+
+plantuml::{includedir}/puml/org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.puml[{diagram_attr}]
+
+
+. 可以解析到其他的 `PropertySourcesPlaceholderConfigurer` 吗?或者可以配置多个 `PropertySourcesPlaceholderConfigurer` 吗?
diff --git a/truman/src/docs/asciidoc/proxy-pattern.adoc b/truman/src/docs/asciidoc/proxy-pattern.adoc
new file mode 100644
index 000000000000..88d642853e73
--- /dev/null
+++ b/truman/src/docs/asciidoc/proxy-pattern.adoc
@@ -0,0 +1,2 @@
+[#proxy-pattern]
+= 代理模式
diff --git a/truman/src/docs/asciidoc/puml/00AA.puml b/truman/src/docs/asciidoc/puml/00AA.puml
new file mode 100644
index 000000000000..20e891ae4a04
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/00AA.puml
@@ -0,0 +1,7 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **标题**
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
diff --git a/truman/src/docs/asciidoc/puml/AbstractApplicationContext-invokeBeanFactoryPostProcessors-2.puml b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-invokeBeanFactoryPostProcessors-2.puml
new file mode 100644
index 000000000000..4eccc81c89ff
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-invokeBeanFactoryPostProcessors-2.puml
@@ -0,0 +1,248 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **""BeanDefinitionRegistryPostProcessor & BeanFactoryPostProcessor"" 调用过程**
+
+
+actor Actor
+participant AbstractApplicationContext << (A,#AADCDF) >>
+participant PostProcessorRegistrationDelegate << (C,#ADD1B2) >>
+participant BeanDefinitionRegistryPostProcessor << (I,#AB9DE1) >>
+participant BeanFactoryPostProcessor << (I,#AB9DE1) >>
+
+Actor -> AbstractApplicationContext: ""refresh""\n重塑容器
+activate AbstractApplicationContext
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""invokeBeanFactoryPostProcessors""
+ activate AbstractApplicationContext #53E516
+ AbstractApplicationContext -> PostProcessorRegistrationDelegate:
+ activate PostProcessorRegistrationDelegate
+ loop #D5E8D4 **遍历所有在 refresh 之前添加的 ""BeanDefinitionRegistryPostProcessor"" 实例**
+
+ |||
+
+ PostProcessorRegistrationDelegate -> BeanDefinitionRegistryPostProcessor: ""postProcessBeanDefinitionRegistry""\n向容器添加 Bean 的定义(也可删除、修改)
+ activate BeanDefinitionRegistryPostProcessor
+ note right: 默认为空。这里是直接获取一个 `List` 类型的对象。可以在在执行\n""refresh"" 之前,通过调用 "AbstractApplicationContext"\n"".addBeanFactoryPostProcessor"" 方法添加。
+
+ |||
+
+ PostProcessorRegistrationDelegate <- BeanDefinitionRegistryPostProcessor
+ deactivate BeanDefinitionRegistryPostProcessor
+
+ |||
+
+ end
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n排序 ""BeanDefinitionRegistryPostProcessor"" 实现类
+ activate PostProcessorRegistrationDelegate #FF33FF
+ |||
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ loop #F8CECC **遍历所有实现 ""PriorityOrdered"" 接口的 ""BeanDefinitionRegistryPostProcessor"" 实例**
+
+ |||
+
+ PostProcessorRegistrationDelegate -> BeanDefinitionRegistryPostProcessor: ""postProcessBeanDefinitionRegistry""\n向容器添加 Bean 的定义(也可删除、修改)
+ activate BeanDefinitionRegistryPostProcessor
+ note over PostProcessorRegistrationDelegate,BeanDefinitionRegistryPostProcessor: 实现 ""PriorityOrdered"" 接口的 ""BeanDefinitionRegistryPostProcessor"" 实例
+ PostProcessorRegistrationDelegate <- BeanDefinitionRegistryPostProcessor
+ deactivate BeanDefinitionRegistryPostProcessor
+
+ |||
+
+ end
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n排序 ""BeanDefinitionRegistryPostProcessor"" 实现类
+ activate PostProcessorRegistrationDelegate #FF33FF
+ |||
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ loop #FFF2CC **遍历所有实现 ""Ordered"" 接口的 ""BeanDefinitionRegistryPostProcessor"" 实例**
+
+ |||
+
+ PostProcessorRegistrationDelegate -> BeanDefinitionRegistryPostProcessor: ""postProcessBeanDefinitionRegistry""\n向容器添加 Bean 的定义(也可删除、修改)
+ activate BeanDefinitionRegistryPostProcessor
+ note over PostProcessorRegistrationDelegate,BeanDefinitionRegistryPostProcessor: 实现 ""Ordered"" 接口的 ""BeanDefinitionRegistryPostProcessor"" 实例
+ PostProcessorRegistrationDelegate <- BeanDefinitionRegistryPostProcessor
+ deactivate BeanDefinitionRegistryPostProcessor
+
+ |||
+
+ end
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n排序 ""BeanDefinitionRegistryPostProcessor"" 实现类
+ activate PostProcessorRegistrationDelegate #FF33FF
+ |||
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ loop #DAE8FC **“递归”遍历剩余所有 ""BeanDefinitionRegistryPostProcessor"" 实例**
+
+ |||
+
+ note over PostProcessorRegistrationDelegate,BeanDefinitionRegistryPostProcessor: 在添加 ""BeanDefinition"" 的过程中,有可能有新加入的 ""BeanDefinitionRegistryPostProcessor"" 类型的 Bean,\n所以要递归调用这个过程,以求把所有的 ""BeanDefinitionRegistryPostProcessor"" 类型的 Bean 都执行到。
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n排序 ""BeanDefinitionRegistryPostProcessor"" 实现类
+ activate PostProcessorRegistrationDelegate #FF33FF
+ |||
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ loop #DDFFFF **遍历剩余的 ""BeanDefinitionRegistryPostProcessor"" 实例**
+
+ |||
+
+ PostProcessorRegistrationDelegate -> BeanDefinitionRegistryPostProcessor: ""postProcessBeanDefinitionRegistry""\n向容器添加 Bean 的定义(也可删除、修改)
+ activate BeanDefinitionRegistryPostProcessor
+ note over PostProcessorRegistrationDelegate,BeanDefinitionRegistryPostProcessor: 剩余所有的 ""BeanDefinitionRegistryPostProcessor"" 实例
+ PostProcessorRegistrationDelegate <- BeanDefinitionRegistryPostProcessor
+ deactivate BeanDefinitionRegistryPostProcessor
+
+ |||
+
+ end
+
+ |||
+
+ end
+
+ |||
+
+ loop #E1D5E7 **遍历所有 ""BeanDefinitionRegistryPostProcessor"" 实例**
+
+ |||
+
+ note over PostProcessorRegistrationDelegate,BeanFactoryPostProcessor: 由于 ""BeanDefinitionRegistryPostProcessor"" 继承了 ""BeanFactoryPostProcessor""。\n所以,所有的 ""BeanDefinitionRegistryPostProcessor"" 实例,也是 ""BeanFactoryPostProcessor"" 实例。
+
+ |||
+
+ PostProcessorRegistrationDelegate -> BeanFactoryPostProcessor: ""postProcessBeanFactory""\n更新容器内 Bean 的定义(增加、删除、修改)
+ activate BeanFactoryPostProcessor
+
+ |||
+
+ PostProcessorRegistrationDelegate <- BeanFactoryPostProcessor
+ deactivate BeanFactoryPostProcessor
+
+ |||
+
+ end
+
+ |||
+
+ loop #D5E8D4 **遍历所有在 refresh 之前添加的 ""BeanFactoryPostProcessor"" 实例**
+
+ |||
+
+ PostProcessorRegistrationDelegate -> BeanFactoryPostProcessor: ""postProcessBeanFactory""\n更新容器内 Bean 的定义(增加、删除、修改)
+ activate BeanFactoryPostProcessor
+
+ |||
+
+ PostProcessorRegistrationDelegate <- BeanFactoryPostProcessor
+ deactivate BeanFactoryPostProcessor
+
+ |||
+
+ end
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n排序 ""BeanFactoryPostProcessor"" 实现类
+ activate PostProcessorRegistrationDelegate #FF33FF
+ |||
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ loop #F8CECC **遍历所有实现了 ""PriorityOrdered"" 的 ""BeanFactoryPostProcessor"" 实例**
+
+ |||
+
+ PostProcessorRegistrationDelegate -> BeanFactoryPostProcessor: ""postProcessBeanFactory""\n更新容器内 Bean 的定义(增加、删除、修改)
+ note over PostProcessorRegistrationDelegate,BeanFactoryPostProcessor: 实现 ""PriorityOrdered"" 接口的 ""BeanFactoryPostProcessor"" 实例
+ activate BeanFactoryPostProcessor
+ PostProcessorRegistrationDelegate <- BeanFactoryPostProcessor
+ deactivate BeanFactoryPostProcessor
+
+ |||
+
+ end
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n排序 ""BeanFactoryPostProcessor"" 实现类
+ activate PostProcessorRegistrationDelegate #FF33FF
+ |||
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ loop #FFF2CC **遍历所有实现了 ""Ordered"" 的 ""BeanFactoryPostProcessor"" 实例**
+
+ |||
+
+ PostProcessorRegistrationDelegate -> BeanFactoryPostProcessor: ""postProcessBeanFactory""\n更新容器内 Bean 的定义(增加、删除、修改)
+ note over PostProcessorRegistrationDelegate,BeanFactoryPostProcessor: 实现 ""Ordered"" 接口的 ""BeanFactoryPostProcessor"" 实例
+ activate BeanFactoryPostProcessor
+ PostProcessorRegistrationDelegate <- BeanFactoryPostProcessor
+ deactivate BeanFactoryPostProcessor
+
+ |||
+
+ end
+
+ |||
+
+ loop #DDFFFF **遍历剩余所有的 ""BeanFactoryPostProcessor"" 实例**
+
+ |||
+
+ PostProcessorRegistrationDelegate -> BeanFactoryPostProcessor: ""postProcessBeanFactory""\n更新容器内 Bean 的定义(增加、删除、修改)
+ note over PostProcessorRegistrationDelegate,BeanFactoryPostProcessor: 剩余所有的 ""BeanFactoryPostProcessor"" 实例
+ activate BeanFactoryPostProcessor
+ PostProcessorRegistrationDelegate <- BeanFactoryPostProcessor
+ deactivate BeanFactoryPostProcessor
+
+ |||
+
+ end
+
+ |||
+
+ AbstractApplicationContext <- PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+ AbstractApplicationContext -> AbstractApplicationContext
+ deactivate AbstractApplicationContext
+
+ |||
+
+Actor <- AbstractApplicationContext: 完成容器初始化
+deactivate AbstractApplicationContext
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
diff --git a/truman/src/docs/asciidoc/puml/AbstractApplicationContext-invokeBeanFactoryPostProcessors.puml b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-invokeBeanFactoryPostProcessors.puml
new file mode 100644
index 000000000000..38b219f574a4
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-invokeBeanFactoryPostProcessors.puml
@@ -0,0 +1,238 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **AbstractApplicationContext.invokeBeanFactoryPostProcessors -- 调用 ""BeanFactoryPostProcessor""**
+
+
+actor Actor
+participant AbstractApplicationContext << (C,#ADD1B2) >>
+participant PostProcessorRegistrationDelegate << (C,#ADD1B2) >>
+participant BeanDefinitionRegistryPostProcessor << (I,#AB9DE1) >>
+note over BeanDefinitionRegistryPostProcessor: ""BeanDefinitionRegistryPostProcessor"" \n 是 ""BeanFactoryPostProcessor"" 的子接口。
+participant List << (I,#AB9DE1) >>
+participant ListableBeanFactory << (I,#AB9DE1) >>
+participant BeanFactoryPostProcessor << (I,#AB9DE1) >>
+
+Actor -> AbstractApplicationContext: ""refresh""\n重塑容器
+activate AbstractApplicationContext
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""invokeBeanFactoryPostProcessors""\n调用 ""BeanFactoryPostProcessor""
+ activate AbstractApplicationContext
+
+ AbstractApplicationContext -> PostProcessorRegistrationDelegate: ""invokeBeanFactoryPostProcessors""\n调用 ""BeanFactoryPostProcessor""
+ activate PostProcessorRegistrationDelegate
+ loop 所有的 ""BeanFactoryPostProcessor""
+ alt #CFFCED 实现 ""BeanDefinitionRegistryPostProcessor"" 接口
+ PostProcessorRegistrationDelegate -> BeanDefinitionRegistryPostProcessor: ""postProcessBeanDefinitionRegistry""\n调用 ""BeanFactoryPostProcessor""
+ activate BeanDefinitionRegistryPostProcessor
+ note over PostProcessorRegistrationDelegate,BeanDefinitionRegistryPostProcessor: 只遍历实现 ""BeanDefinitionRegistryPostProcessor"" 的 ""BeanFactoryPostProcessor""
+ PostProcessorRegistrationDelegate <- BeanDefinitionRegistryPostProcessor
+ deactivate BeanDefinitionRegistryPostProcessor
+
+ |||
+
+ PostProcessorRegistrationDelegate -> List: ""add""\n添加元素
+ activate List
+ note over PostProcessorRegistrationDelegate,List: 添加到 ""registryProcessors"" 集合中
+ PostProcessorRegistrationDelegate <- List
+ deactivate List
+ |||
+ else #FFF7FA 没有实现 ""BeanDefinitionRegistryPostProcessor"" 接口
+ PostProcessorRegistrationDelegate -> List: ""add""\n添加元素
+ activate List
+ note over PostProcessorRegistrationDelegate,List: 添加到 ""regularPostProcessors"" 集合中
+ PostProcessorRegistrationDelegate <- List
+ deactivate List
+ |||
+ end
+ end
+
+ |||
+ ==首先,调用实现了 ""PriorityOrdered"" 接口的 ""BeanDefinitionRegistryPostProcessors"" 的 ""postProcessBeanDefinitionRegistry"" 方法 ==
+ |||
+
+ PostProcessorRegistrationDelegate -> ListableBeanFactory: ""getBeanNamesForType""\n获取指定类型的 Bean 名称
+ activate ListableBeanFactory
+ note over PostProcessorRegistrationDelegate,ListableBeanFactory: 获取类型为 ""BeanDefinitionRegistryPostProcessor"" 的 Bean 名称
+ PostProcessorRegistrationDelegate <- ListableBeanFactory
+ deactivate ListableBeanFactory
+
+ |||
+
+ loop 上述获取的 Bean 名称
+ PostProcessorRegistrationDelegate -> ListableBeanFactory: ""isTypeMatch""\n检查 Bean 是否为指定类型
+ activate ListableBeanFactory
+ note over PostProcessorRegistrationDelegate,ListableBeanFactory: 筛选出实现了 ""PriorityOrdered"" 接口的 ""BeanFactoryPostProcessor"",供后面优先调用。
+ PostProcessorRegistrationDelegate <- ListableBeanFactory
+ deactivate ListableBeanFactory
+ end
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n对上述筛选出来的 Bean 进行排序
+ activate PostProcessorRegistrationDelegate
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ PostProcessorRegistrationDelegate -> List: ""addAll""\n将上述 Bean 全部添加到 ""registryProcessors"" 集合中
+ activate List
+ note over PostProcessorRegistrationDelegate,List: 添加到 ""registryProcessors"" 集合中
+ PostProcessorRegistrationDelegate <- List
+ deactivate List
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""invokeBeanDefinitionRegistryPostProcessors""\n调用 ""BeanDefinitionRegistryPostProcessor""
+ activate PostProcessorRegistrationDelegate
+ loop 上述筛选出来的所有 ""BeanFactoryPostProcessor""
+ PostProcessorRegistrationDelegate -> BeanDefinitionRegistryPostProcessor: ""postProcessBeanDefinitionRegistry""\n调用 ""BeanFactoryPostProcessor""
+ activate BeanDefinitionRegistryPostProcessor
+ note over PostProcessorRegistrationDelegate,BeanDefinitionRegistryPostProcessor: 只遍历实现 ""PriorityOrdered"" 接口的 ""BeanDefinitionRegistryPostProcessor"" Bean
+ PostProcessorRegistrationDelegate <- BeanDefinitionRegistryPostProcessor
+ deactivate BeanDefinitionRegistryPostProcessor
+ end
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+ ==其次,调用实现了 ""Ordered"" 接口的 ""BeanDefinitionRegistryPostProcessors"" 的 ""postProcessBeanDefinitionRegistry"" 方法 ==
+ |||
+
+ PostProcessorRegistrationDelegate -> ListableBeanFactory: ""getBeanNamesForType""\n获取指定类型的 Bean 名称
+ activate ListableBeanFactory
+ note over PostProcessorRegistrationDelegate,ListableBeanFactory: 获取类型为 ""BeanDefinitionRegistryPostProcessor"" 的 Bean 名称
+ PostProcessorRegistrationDelegate <- ListableBeanFactory
+ deactivate ListableBeanFactory
+
+ |||
+
+ loop 上述获取的 Bean 名称
+ PostProcessorRegistrationDelegate -> ListableBeanFactory: ""isTypeMatch""\n检查 Bean 是否为指定类型
+ activate ListableBeanFactory
+ note over PostProcessorRegistrationDelegate,ListableBeanFactory: 筛选出实现了 ""Ordered"" 接口的 ""BeanFactoryPostProcessor"",供后面优先调用。
+ PostProcessorRegistrationDelegate <- ListableBeanFactory
+ deactivate ListableBeanFactory
+ end
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n对上述筛选出来的 Bean 进行排序
+ activate PostProcessorRegistrationDelegate
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ PostProcessorRegistrationDelegate -> List: ""addAll""\n将上述 Bean 全部添加到 ""registryProcessors"" 集合中
+ activate List
+ note over PostProcessorRegistrationDelegate,List: 添加到 ""registryProcessors"" 集合中
+ PostProcessorRegistrationDelegate <- List
+ deactivate List
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""invokeBeanDefinitionRegistryPostProcessors""\n调用 ""BeanDefinitionRegistryPostProcessor""
+ activate PostProcessorRegistrationDelegate
+ loop 上述筛选出来的所有 ""BeanFactoryPostProcessor""
+ PostProcessorRegistrationDelegate -> BeanDefinitionRegistryPostProcessor: ""postProcessBeanDefinitionRegistry""\n调用 ""BeanFactoryPostProcessor""
+ activate BeanDefinitionRegistryPostProcessor
+ note over PostProcessorRegistrationDelegate,BeanDefinitionRegistryPostProcessor: 只遍历实现 ""PriorityOrdered"" 接口的 ""BeanDefinitionRegistryPostProcessor"" Bean
+ PostProcessorRegistrationDelegate <- BeanDefinitionRegistryPostProcessor
+ deactivate BeanDefinitionRegistryPostProcessor
+ end
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+ ==最后,调用剩余的 ""BeanDefinitionRegistryPostProcessors"" 的 ""postProcessBeanDefinitionRegistry"" 方法==
+ |||
+ loop 有新创建出来的 ""BeanDefinitionRegistryPostProcessor"" 就遍历
+ PostProcessorRegistrationDelegate -> ListableBeanFactory: ""getBeanNamesForType""\n获取指定类型的 Bean 名称
+ activate ListableBeanFactory
+ note over PostProcessorRegistrationDelegate,ListableBeanFactory: 获取类型为 ""BeanDefinitionRegistryPostProcessor"" 的 Bean 名称
+ PostProcessorRegistrationDelegate <- ListableBeanFactory
+ deactivate ListableBeanFactory
+
+ |||
+
+ loop 上述获取的 Bean 名称
+ PostProcessorRegistrationDelegate -> ListableBeanFactory: ""isTypeMatch""\n检查 Bean 是否为指定类型
+ activate ListableBeanFactory
+ note over PostProcessorRegistrationDelegate,ListableBeanFactory: 筛选出实现了 ""Ordered"" 接口的 ""BeanFactoryPostProcessor"",供后面优先调用。
+ PostProcessorRegistrationDelegate <- ListableBeanFactory
+ deactivate ListableBeanFactory
+ end
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n对上述筛选出来的 Bean 进行排序
+ activate PostProcessorRegistrationDelegate
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ PostProcessorRegistrationDelegate -> List: ""addAll""\n将上述 Bean 全部添加到 ""registryProcessors"" 集合中
+ activate List
+ note over PostProcessorRegistrationDelegate,List: 添加到 ""registryProcessors"" 集合中
+ PostProcessorRegistrationDelegate <- List
+ deactivate List
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""invokeBeanDefinitionRegistryPostProcessors""\n调用 ""BeanDefinitionRegistryPostProcessor""
+ activate PostProcessorRegistrationDelegate
+ loop 上述筛选出来的所有 ""BeanFactoryPostProcessor""
+ PostProcessorRegistrationDelegate -> BeanDefinitionRegistryPostProcessor: ""postProcessBeanDefinitionRegistry""\n调用 ""BeanFactoryPostProcessor""
+ activate BeanDefinitionRegistryPostProcessor
+ note over PostProcessorRegistrationDelegate,BeanDefinitionRegistryPostProcessor: 只遍历实现 ""PriorityOrdered"" 接口的 ""BeanDefinitionRegistryPostProcessor"" Bean
+ PostProcessorRegistrationDelegate <- BeanDefinitionRegistryPostProcessor
+ deactivate BeanDefinitionRegistryPostProcessor
+ end
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+ end
+
+ |||
+ ==结尾,调用 ""BeanFactoryPostProcessor"" 的 ""postProcessBeanFactory"" 方法 ==
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""invokeBeanFactoryPostProcessors""\n调用 ""BeanFactoryPostProcessor""\n 的 ""postProcessBeanFactory""
+ activate PostProcessorRegistrationDelegate
+ loop 遍历 ""registryProcessors""
+ PostProcessorRegistrationDelegate -> BeanFactoryPostProcessor: ""postProcessBeanFactory""\n调用 ""BeanFactoryPostProcessor""\n 的 ""postProcessBeanFactory""
+ activate BeanFactoryPostProcessor
+ note over PostProcessorRegistrationDelegate,BeanFactoryPostProcessor: 遍历 ""registryProcessors""
+ PostProcessorRegistrationDelegate <- BeanFactoryPostProcessor
+ deactivate BeanFactoryPostProcessor
+ end
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""invokeBeanFactoryPostProcessors""\n调用 ""BeanFactoryPostProcessor""\n 的 ""postProcessBeanFactory""
+ activate PostProcessorRegistrationDelegate
+ loop 遍历 ""regularPostProcessors""
+ PostProcessorRegistrationDelegate -> BeanFactoryPostProcessor: ""postProcessBeanFactory""\n调用 ""BeanFactoryPostProcessor""\n 的 ""postProcessBeanFactory""
+ activate BeanFactoryPostProcessor
+ note over PostProcessorRegistrationDelegate,BeanFactoryPostProcessor: 遍历 ""regularPostProcessors""
+ PostProcessorRegistrationDelegate <- BeanFactoryPostProcessor
+ deactivate BeanFactoryPostProcessor
+ end
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ AbstractApplicationContext <- PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ AbstractApplicationContext -> AbstractApplicationContext
+ deactivate AbstractApplicationContext
+
+Actor <- AbstractApplicationContext: 完成容器初始化
+deactivate AbstractApplicationContext
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
diff --git a/truman/src/docs/asciidoc/puml/AbstractApplicationContext-obtainFreshBeanFactory.puml b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-obtainFreshBeanFactory.puml
new file mode 100644
index 000000000000..1690bae40514
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-obtainFreshBeanFactory.puml
@@ -0,0 +1,174 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **AbstractApplicationContext.obtainFreshBeanFactory -- XML 配置文件解析**
+
+
+actor Actor
+participant AbstractApplicationContext << (C,#ADD1B2) >>
+participant AbstractRefreshableApplicationContext << (C,#ADD1B2) >>
+participant AbstractXmlApplicationContext << (C,#ADD1B2) >>
+participant XmlBeanDefinitionReader << (C,#ADD1B2) >>
+participant ResourceLoader << (I,#AB9DE1) >>
+participant BeanDefinitionDocumentReader << (C,#ADD1B2) >>
+participant BeanDefinitionParserDelegate << (C,#ADD1B2) >>
+participant DefaultListableBeanFactory << (C,#ADD1B2) >>
+participant NamespaceHandler << (I,#AB9DE1) >>
+
+Actor -> AbstractApplicationContext: ""refresh""\n重塑容器
+activate AbstractApplicationContext
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""obtainFreshBeanFactory""\n获取BeanFactory
+ activate AbstractApplicationContext
+
+ AbstractApplicationContext -> AbstractRefreshableApplicationContext: ""refreshBeanFactory""\n刷新BeanFactory
+ activate AbstractRefreshableApplicationContext
+
+ AbstractRefreshableApplicationContext -> AbstractXmlApplicationContext: ""loadBeanDefinitions""\n加载 ""BeanDefinition""
+ activate AbstractXmlApplicationContext
+
+ AbstractXmlApplicationContext -> AbstractXmlApplicationContext: ""loadBeanDefinitions""\n加载 ""BeanDefinition""
+ activate AbstractXmlApplicationContext
+
+ AbstractXmlApplicationContext -> XmlBeanDefinitionReader: ""loadBeanDefinitions""\n加载 ""BeanDefinition""
+ activate XmlBeanDefinitionReader
+ note right #FFAAAA: ""loadBeanDefinitions"" 方法被重\n载了多次,在这里也被调用了多次。
+
+ XmlBeanDefinitionReader -> ResourceLoader: ""getResources""\n加载 ""Resource""
+ activate ResourceLoader
+ note over XmlBeanDefinitionReader,ResourceLoader: 将配置路径转化成 ""Resource"" 对象。\n注:这里的路径也支持占位符替换。可以从环境变量中取值。
+ XmlBeanDefinitionReader <- ResourceLoader
+ deactivate ResourceLoader
+
+ |||
+
+ XmlBeanDefinitionReader -> XmlBeanDefinitionReader: ""doLoadBeanDefinitions""\n加载 ""BeanDefinition""
+ activate XmlBeanDefinitionReader
+ XmlBeanDefinitionReader -> BeanDefinitionDocumentReader: ""registerBeanDefinitions""\n注册 ""BeanDefinition""
+ activate BeanDefinitionDocumentReader
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader: ""doRegisterBeanDefinitions""\n注册 ""BeanDefinition""
+ activate BeanDefinitionDocumentReader
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader: ""parseBeanDefinitions""\n处理 ""BeanDefinition"" 定义
+ activate BeanDefinitionDocumentReader
+ note right #FFAAAA: 对于 XML 的解析都在次方法中!
+ alt #LightGreen **默认命名空间(即 ""beans"")**
+ |||
+ group#yellow """"
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader: ""importBeanDefinitionResource""\n处理 """" 标签
+ activate BeanDefinitionDocumentReader
+ note right #FFAAAA: 该方法时序图做了极大简化处理。\n不过,大致流程是这样的。
+ BeanDefinitionDocumentReader -> ResourceLoader: ""getResources""\n加载 ""Resource""
+ activate ResourceLoader
+ note over BeanDefinitionDocumentReader,ResourceLoader: 将配置路径转化成 ""Resource"" 对象。\n注:这里的路径也支持占位符替换。可以从环境变量中取值。
+ BeanDefinitionDocumentReader <- ResourceLoader
+ deactivate ResourceLoader
+ |||
+ BeanDefinitionDocumentReader -> XmlBeanDefinitionReader: ""loadBeanDefinitions""\n加载 ""BeanDefinition""
+ activate XmlBeanDefinitionReader
+ note over BeanDefinitionDocumentReader,XmlBeanDefinitionReader: “递归”调用 ""loadBeanDefinitions"" 方法,解析配置文件并加载 Bean。
+ BeanDefinitionDocumentReader <- XmlBeanDefinitionReader
+ deactivate XmlBeanDefinitionReader
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader
+ deactivate BeanDefinitionDocumentReader
+ |||
+ end
+
+ |||
+
+ group#yellow """"
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader: ""processAliasRegistration""\n处理 """" 标签
+ activate BeanDefinitionDocumentReader
+ BeanDefinitionDocumentReader -> DefaultListableBeanFactory: ""registerAlias""\n注册别名
+ activate DefaultListableBeanFactory
+ note over BeanDefinitionDocumentReader,DefaultListableBeanFactory: 其实,这里调用的是 ""AliasRegistry"" 的 ""registerAlias"" 方法。\n 但, ""DefaultListableBeanFactory"" 是 ""AliasRegistry"" 的一个实现类。
+ BeanDefinitionDocumentReader -> DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader
+ deactivate BeanDefinitionDocumentReader
+ |||
+ end
+
+ |||
+
+ group#yellow """"
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader: ""processBeanDefinition""\n处理 """" 标签
+ activate BeanDefinitionDocumentReader
+ BeanDefinitionDocumentReader -> BeanDefinitionParserDelegate: ""parseBeanDefinitionElement""\n处理 """" 标签元素
+ activate BeanDefinitionParserDelegate
+ note over BeanDefinitionDocumentReader,BeanDefinitionParserDelegate: 这里也一并处理 """" 标签的子标签,比如 """" 等标签。\n还会设置一些默认值,比如 ""lazy-init"" 等
+ BeanDefinitionDocumentReader -> BeanDefinitionParserDelegate
+ deactivate BeanDefinitionParserDelegate
+
+ |||
+
+ BeanDefinitionDocumentReader -> DefaultListableBeanFactory: ""registerBeanDefinition""\n注册 ""BeanDefinition""
+ activate DefaultListableBeanFactory
+ note over BeanDefinitionDocumentReader,DefaultListableBeanFactory: 其实,这里调用的是 ""BeanDefinitionRegistry"" 的 ""registerBeanDefinition"" 方法。\n 但, ""DefaultListableBeanFactory"" 是 ""BeanDefinitionRegistry"" 的一个实现类。
+ BeanDefinitionDocumentReader -> DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+ loop 上述 ""BeanDefinition"" 对象中包含的所有别名
+ BeanDefinitionDocumentReader -> DefaultListableBeanFactory: ""registerAlias""\n注册别名
+ activate DefaultListableBeanFactory
+ note over BeanDefinitionDocumentReader,DefaultListableBeanFactory : 其实,这里调用的是 ""AliasRegistry"" 的方法。\n但, ""DefaultListableBeanFactory"" 是 ""AliasRegistry"" 的一个实现类。
+ BeanDefinitionDocumentReader -> DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+ end
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader
+ deactivate BeanDefinitionDocumentReader
+ |||
+ end
+
+ |||
+
+ group#yellow """"
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader: ""doRegisterBeanDefinitions""\n处理 """" 标签
+ activate BeanDefinitionDocumentReader
+ note over BeanDefinitionDocumentReader,BeanDefinitionDocumentReader:递归调用,处理 """" 标签。
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader
+ deactivate BeanDefinitionDocumentReader
+ |||
+ end
+ |||
+ else #FFF0C5 **除 ""beans"" 外的其他命名空间**
+ BeanDefinitionDocumentReader -> BeanDefinitionParserDelegate: ""parseCustomElement""\n处理自定义标签元素
+ activate BeanDefinitionParserDelegate
+ BeanDefinitionParserDelegate -> NamespaceHandler: ""parse""\n处理自定义标签元素
+ activate NamespaceHandler
+ note over BeanDefinitionParserDelegate,NamespaceHandler: 除 ""beans"" 命名空间外,其他所有标签都是通过该机制来扩展 Spring 的能力的。\n只需将 Spring 其他命名空间的或自定义命名空间的标签处理成 ""BeanDefinition"" 对象即可,\n后续,Spring 会调用 ""BeanDefinitionRegistry"" 的 ""registerBeanDefinition"" 方法注册该对象。
+ BeanDefinitionParserDelegate <- NamespaceHandler
+ deactivate NamespaceHandler
+ BeanDefinitionDocumentReader -> BeanDefinitionParserDelegate
+ deactivate BeanDefinitionParserDelegate
+ |||
+ end
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader
+ deactivate BeanDefinitionDocumentReader
+ BeanDefinitionDocumentReader -> BeanDefinitionDocumentReader
+ deactivate BeanDefinitionDocumentReader
+ XmlBeanDefinitionReader <- BeanDefinitionDocumentReader
+ deactivate BeanDefinitionDocumentReader
+ XmlBeanDefinitionReader -> XmlBeanDefinitionReader
+ deactivate XmlBeanDefinitionReader
+
+ AbstractXmlApplicationContext <- XmlBeanDefinitionReader
+ deactivate XmlBeanDefinitionReader
+
+ AbstractXmlApplicationContext -> AbstractXmlApplicationContext
+ deactivate AbstractXmlApplicationContext
+
+ AbstractRefreshableApplicationContext <- AbstractXmlApplicationContext
+ deactivate AbstractXmlApplicationContext
+
+ AbstractApplicationContext <- AbstractRefreshableApplicationContext
+ deactivate AbstractRefreshableApplicationContext
+
+ AbstractApplicationContext -> AbstractApplicationContext
+ deactivate AbstractApplicationContext
+
+Actor <- AbstractApplicationContext: 完成容器初始化
+deactivate AbstractApplicationContext
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
diff --git a/truman/src/docs/asciidoc/puml/AbstractApplicationContext-prepareBeanFactory.puml b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-prepareBeanFactory.puml
new file mode 100644
index 000000000000..a927b8510419
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-prepareBeanFactory.puml
@@ -0,0 +1,168 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **AbstractApplicationContext.prepareBeanFactory -- 准备 ""BeanFactory""**
+
+
+actor Actor
+participant AbstractApplicationContext << (C,#ADD1B2) >>
+participant DefaultListableBeanFactory << (C,#ADD1B2) >>
+
+Actor -> AbstractApplicationContext: ""refresh""\n重塑容器
+activate AbstractApplicationContext
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""prepareBeanFactory""\n准备 ""BeanFactory""
+ activate AbstractApplicationContext
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""setBeanClassLoader""\n设置类加载器
+ activate DefaultListableBeanFactory
+ |||
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""setBeanExpressionResolver""\n设置Spring表达式解析器
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: ""StandardBeanExpressionResolver""
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""addPropertyEditorRegistrar""\n添加默认 ""PropertyEditor""
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: ""ResourceEditorRegistrar""
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""addBeanPostProcessor""\n添加 ""BeanPostProcessor""
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: ""ApplicationContextAwareProcessor""\n处理各种 ""Aware"" 接口,比如 ""ApplicationContextAware"" 等
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""ignoreDependencyInterface""\n添加“依赖忽略接口”
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: 忽略各种 ""Aware"" 接口,\n这些接口由上述 ""ApplicationContextAwareProcessor"" 处理,\n不需要再执行依赖注入。
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""registerResolvableDependency""\n添加“可解析的依赖”
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: ""BeanFactory""、""ResourceLoader""、\n""ApplicationEventPublisher""、""ApplicationContext""
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""addBeanPostProcessor""\n添加 ""BeanPostProcessor""
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: ""ApplicationListenerDetector""\n探测 Bean 是否为 ""ApplicationListener""
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ alt 不是 Native 镜像 && 包含了 loadTimeWeaver Bean
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""addBeanPostProcessor""\n添加 ""BeanPostProcessor""
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: ""LoadTimeWeaverAwareProcessor""\n加载时织入
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""setTempClassLoader""\n设置临时类加载器
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: ""ContextTypeMatchClassLoader""
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+ end
+
+ |||
+
+ alt ""BeanFactory"" 实例中不含 ""environment""
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""containsLocalBean""\n是否包含 ""environment""
+ activate DefaultListableBeanFactory
+ |||
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""registerSingleton""\n注册 Bean
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: ""environment"" // 此为 Bean 名称
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+ end
+
+ |||
+
+ alt ""BeanFactory"" 实例中不含 ""systemProperties""
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""containsLocalBean""\n是否包含 ""systemProperties""
+ activate DefaultListableBeanFactory
+ |||
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""registerSingleton""\n注册 Bean
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: ""systemProperties"" // 此为 Bean 名称
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+ end
+
+ |||
+
+ alt ""BeanFactory"" 实例中不含 ""systemEnvironment""
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""containsLocalBean""\n是否包含 ""systemEnvironment""
+ activate DefaultListableBeanFactory
+ |||
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""registerSingleton""\n注册 Bean
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: ""systemEnvironment"" // 此为 Bean 名称
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+ end
+
+ |||
+
+ alt ""BeanFactory"" 实例中不含 ""applicationStartup""
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""containsLocalBean""\n是否包含 ""applicationStartup""
+ activate DefaultListableBeanFactory
+ |||
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+
+ |||
+
+ AbstractApplicationContext -> DefaultListableBeanFactory: ""registerSingleton""\n注册 Bean
+ activate DefaultListableBeanFactory
+ note over AbstractApplicationContext,DefaultListableBeanFactory: ""applicationStartup"" // 此为 Bean 名称
+ AbstractApplicationContext <- DefaultListableBeanFactory
+ deactivate DefaultListableBeanFactory
+ end
+
+ AbstractApplicationContext -> AbstractApplicationContext
+ deactivate AbstractApplicationContext
+
+Actor <- AbstractApplicationContext: 完成容器初始化
+deactivate AbstractApplicationContext
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
diff --git a/truman/src/docs/asciidoc/puml/AbstractApplicationContext-refresh.puml b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-refresh.puml
new file mode 100644
index 000000000000..3231a0336f78
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-refresh.puml
@@ -0,0 +1,91 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **""AbstractApplicationContext.refresh"" -- 重塑容器**
+
+
+actor Actor
+participant AbstractApplicationContext << (C,#ADD1B2) >>
+participant BeanFactoryPostProcessor << (I,#AB9DE1) >>
+
+Actor -> AbstractApplicationContext: ""refresh""\n重塑容器
+activate AbstractApplicationContext
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""prepareRefresh""\n准备环境
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""obtainFreshBeanFactory""\n获取BeanFactory
+ note right: 加载并解析配置文件
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""prepareBeanFactory""\n准备 ""BeanFactory""
+ note right: 忽略各种 Aware 接口的注入;同时,\n注册一些必要的 Bean,比如 ""BeanFactory""。
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""postProcessBeanFactory""\n对 ""BeanFactory"" 做后期处理
+ note right: 预留扩展点,\n目前是空实现
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""invokeBeanFactoryPostProcessors""\n调用 ""BeanFactoryPostProcessor"" 的 \n""postProcessBeanFactory"" 方法
+ activate AbstractApplicationContext #53E516
+
+ loop **遍历所有 ""BeanFactoryPostProcessor"" 实例**
+ AbstractApplicationContext -> BeanFactoryPostProcessor: ""postProcessBeanFactory""\n更新容器内 Bean 的定义(增加、删除、修改)
+ activate BeanFactoryPostProcessor
+ note left #FFAAAA: ""BeanFactoryPostProcessor""\n是 Spring 容器非常重要的扩展点!\n\n很多第三方框架集成 Spring 就是\n用的该扩展点,比如 MyBATIS。
+
+ |||
+
+ AbstractApplicationContext <- BeanFactoryPostProcessor: 完成 Bean 定义的更新
+ deactivate BeanFactoryPostProcessor
+ |||
+ end
+
+ AbstractApplicationContext -> AbstractApplicationContext
+ deactivate AbstractApplicationContext
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""registerBeanPostProcessors""\n注册 ""BeanPostProcessor""
+ note right #FFAAAA: ""BeanPostProcessor"" \n是 Spring 非常重要的扩展点!\n\n依赖注入,AOP切面生成等就是\n通过不同 ""BeanPostProcessor""\n实例来完成的。
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""initMessageSource""\n初始化 ""MessageSource""
+ note right: 国际化相关
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""initApplicationEventMulticaster""\n初始化应用事件广播器
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""onRefresh""
+ note right: 在 Web 容器中,注册\n""DispatchServlet"" 等九大组件
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""registerListeners""\n注册事件监听器
+ note right: 将 ""ApplicationListener"" 类型的 Bean 注册\n到 ""ApplicationEventMulticaster"" 中,\n后续容器启动完成事件即由此广播并处理。
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""finishBeanFactoryInitialization""\n完成预初始化
+ note right: 完成非懒加载的\n单例 Bean 实例化
+
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""finishRefresh""\n完成重塑
+ note right: 删除一些不必要的配置信息。\n最后,广播容器启动完成的消息。
+
+ |||
+
+Actor <- AbstractApplicationContext: 完成容器初始化
+deactivate AbstractApplicationContext
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
diff --git a/truman/src/docs/asciidoc/puml/AbstractApplicationContext-registerBeanPostProcessors.puml b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-registerBeanPostProcessors.puml
new file mode 100644
index 000000000000..00520b7fa9a6
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/AbstractApplicationContext-registerBeanPostProcessors.puml
@@ -0,0 +1,197 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **AbstractApplicationContext.registerBeanPostProcessors -- 注册 ""BeanPostProcessor""**
+
+
+actor Actor
+participant AbstractApplicationContext << (C,#ADD1B2) >>
+participant PostProcessorRegistrationDelegate << (C,#ADD1B2) >>
+participant ConfigurableListableBeanFactory << (I,#AB9DE1) >>
+note over ConfigurableListableBeanFactory: 为了简化,所有 ""BeanFactory"" \n 相关操作,都指向该类。
+participant List << (I,#AB9DE1) >>
+
+Actor -> AbstractApplicationContext: ""refresh""\n重塑容器
+activate AbstractApplicationContext
+ |||
+
+ AbstractApplicationContext -> AbstractApplicationContext: ""registerBeanPostProcessors""\n注册 ""BeanPostProcessor""
+ activate AbstractApplicationContext
+ AbstractApplicationContext -> PostProcessorRegistrationDelegate: ""registerBeanPostProcessors""\n处理 ""BeanPostProcessor"" 注册
+ activate PostProcessorRegistrationDelegate
+
+ PostProcessorRegistrationDelegate -> ConfigurableListableBeanFactory: ""getBeanNamesForType""\n获取类型为 ""BeanPostProcessor"" 的 Bean 名称
+ activate ConfigurableListableBeanFactory
+ |||
+ PostProcessorRegistrationDelegate <- ConfigurableListableBeanFactory
+ deactivate ConfigurableListableBeanFactory
+
+ |||
+
+ PostProcessorRegistrationDelegate -> ConfigurableListableBeanFactory: ""addBeanPostProcessor""\n添加 ""BeanPostProcessor""
+ activate ConfigurableListableBeanFactory
+ note over PostProcessorRegistrationDelegate, ConfigurableListableBeanFactory: 添加类型为 ""BeanPostProcessorChecker"" 的 ""BeanPostProcessor""
+ PostProcessorRegistrationDelegate <- ConfigurableListableBeanFactory
+ deactivate ConfigurableListableBeanFactory
+
+ |||
+
+ loop 第一步获取的 ""postProcessorNames""
+ alt #Fuchsia 类型匹配 ""PriorityOrdered""
+ PostProcessorRegistrationDelegate -> List: ""add""\n添加元素
+ activate List
+ note over PostProcessorRegistrationDelegate, List: 添加到 ""priorityOrderedPostProcessors"" 集合中
+ PostProcessorRegistrationDelegate <- List
+ deactivate List
+ |||
+ alt 如果是 ""MergedBeanDefinitionPostProcessor"" 类型
+ PostProcessorRegistrationDelegate -> List: ""add""\n添加元素
+ activate List
+ note over PostProcessorRegistrationDelegate, List: 再添加到 ""internalPostProcessors"" 集合中
+ PostProcessorRegistrationDelegate <- List
+ deactivate List
+ |||
+ end
+ |||
+ else #Yellow 类型匹配 ""Ordered""
+ PostProcessorRegistrationDelegate -> List: ""add""\n添加元素
+ activate List
+ note over PostProcessorRegistrationDelegate, List: 添加到 ""orderedPostProcessorNames"" 集合中
+ PostProcessorRegistrationDelegate <- List
+ deactivate List
+ |||
+ else #DodgerBlue
+ PostProcessorRegistrationDelegate -> List: ""add""\n添加元素
+ activate List
+ note over PostProcessorRegistrationDelegate, List: 添加到 ""nonOrderedPostProcessorNames"" 集合中
+ PostProcessorRegistrationDelegate <- List
+ deactivate List
+ |||
+ end
+ end
+
+ group #Fuchsia
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n排序
+ activate PostProcessorRegistrationDelegate
+ note over PostProcessorRegistrationDelegate,PostProcessorRegistrationDelegate: 对 ""priorityOrderedPostProcessors"" 进行排序
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""registerBeanPostProcessors""\n注册 ""BeanPostProcessor""
+ activate PostProcessorRegistrationDelegate
+ PostProcessorRegistrationDelegate -> ConfigurableListableBeanFactory: ""addBeanPostProcessors""\n添加 ""BeanPostProcessor""
+ activate ConfigurableListableBeanFactory
+ note over PostProcessorRegistrationDelegate, ConfigurableListableBeanFactory: 注册 ""priorityOrderedPostProcessors"" 集合中的 ""BeanPostProcessor""
+ PostProcessorRegistrationDelegate <- ConfigurableListableBeanFactory
+ deactivate ConfigurableListableBeanFactory
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+ |||
+ end
+
+ |||
+
+ group #Yellow
+ loop 第一步获取的 ""orderedPostProcessorNames""
+ PostProcessorRegistrationDelegate -> ConfigurableListableBeanFactory: ""getBean""\n获取指定名称的 Bean
+ activate ConfigurableListableBeanFactory
+ note over PostProcessorRegistrationDelegate, ConfigurableListableBeanFactory: 获取 ""orderedPostProcessorNames"" 集合中的 ""BeanPostProcessor""
+ PostProcessorRegistrationDelegate <- ConfigurableListableBeanFactory
+ deactivate ConfigurableListableBeanFactory
+ end
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n排序
+ activate PostProcessorRegistrationDelegate
+ note over PostProcessorRegistrationDelegate,PostProcessorRegistrationDelegate: 对 ""orderedPostProcessorNames"" 进行排序
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""registerBeanPostProcessors""\n注册 ""BeanPostProcessor""
+ activate PostProcessorRegistrationDelegate
+ PostProcessorRegistrationDelegate -> ConfigurableListableBeanFactory: ""addBeanPostProcessors""\n添加 ""BeanPostProcessor""
+ activate ConfigurableListableBeanFactory
+ note over PostProcessorRegistrationDelegate, ConfigurableListableBeanFactory: 注册 ""orderedPostProcessorNames"" 集合中的 ""BeanPostProcessor""
+ PostProcessorRegistrationDelegate <- ConfigurableListableBeanFactory
+ deactivate ConfigurableListableBeanFactory
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+ |||
+ end
+
+ |||
+
+ group #DodgerBlue
+ loop 第一步获取的 ""nonOrderedPostProcessorNames""
+ PostProcessorRegistrationDelegate -> ConfigurableListableBeanFactory: ""getBean""\n获取指定名称的 Bean
+ activate ConfigurableListableBeanFactory
+ note over PostProcessorRegistrationDelegate, ConfigurableListableBeanFactory: 获取 ""nonOrderedPostProcessorNames"" 集合中的 ""BeanPostProcessor""
+ PostProcessorRegistrationDelegate <- ConfigurableListableBeanFactory
+ deactivate ConfigurableListableBeanFactory
+ |||
+ alt 如果是 ""MergedBeanDefinitionPostProcessor"" 类型
+ PostProcessorRegistrationDelegate -> List: ""add""\n添加元素
+ activate List
+ note over PostProcessorRegistrationDelegate, List: 再添加到 ""internalPostProcessors"" 集合中
+ PostProcessorRegistrationDelegate <- List
+ deactivate List
+ |||
+ end
+ end
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""registerBeanPostProcessors""\n注册 ""BeanPostProcessor""
+ activate PostProcessorRegistrationDelegate
+ PostProcessorRegistrationDelegate -> ConfigurableListableBeanFactory: ""addBeanPostProcessors""\n添加 ""BeanPostProcessor""
+ activate ConfigurableListableBeanFactory
+ note over PostProcessorRegistrationDelegate, ConfigurableListableBeanFactory: 注册 ""orderedPostProcessorNames"" 集合中的 ""BeanPostProcessor""
+ PostProcessorRegistrationDelegate <- ConfigurableListableBeanFactory
+ deactivate ConfigurableListableBeanFactory
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+ |||
+ end
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""sortPostProcessors""\n排序
+ activate PostProcessorRegistrationDelegate
+ note over PostProcessorRegistrationDelegate,PostProcessorRegistrationDelegate: 对 ""internalPostProcessors"" 进行排序
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+
+ |||
+
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate: ""registerBeanPostProcessors""\n注册 ""BeanPostProcessor""
+ activate PostProcessorRegistrationDelegate
+ PostProcessorRegistrationDelegate -> ConfigurableListableBeanFactory: ""addBeanPostProcessors""\n添加 ""BeanPostProcessor""
+ activate ConfigurableListableBeanFactory
+ note over PostProcessorRegistrationDelegate, ConfigurableListableBeanFactory: 注册 ""internalPostProcessors"" 集合中的 ""BeanPostProcessor""\n这样处理后,这些 ""BeanPostProcessor"" 就在列表的最后,也就是最后生效。
+ PostProcessorRegistrationDelegate <- ConfigurableListableBeanFactory
+ deactivate ConfigurableListableBeanFactory
+ PostProcessorRegistrationDelegate -> PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+ |||
+
+ PostProcessorRegistrationDelegate -> ConfigurableListableBeanFactory: ""addBeanPostProcessor""\n添加 ""BeanPostProcessor""
+ activate ConfigurableListableBeanFactory
+ note over PostProcessorRegistrationDelegate, ConfigurableListableBeanFactory: 添加类型为 ""ApplicationListenerDetector"" 的 ""BeanPostProcessor""
+ PostProcessorRegistrationDelegate <- ConfigurableListableBeanFactory
+ deactivate ConfigurableListableBeanFactory
+ |||
+ AbstractApplicationContext <- PostProcessorRegistrationDelegate
+ deactivate PostProcessorRegistrationDelegate
+ AbstractApplicationContext -> AbstractApplicationContext
+ deactivate AbstractApplicationContext
+
+ |||
+
+Actor <- AbstractApplicationContext: 完成容器初始化
+deactivate AbstractApplicationContext
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
diff --git a/truman/src/docs/asciidoc/puml/AnnotationAwareAspectJAutoProxyCreator.puml b/truman/src/docs/asciidoc/puml/AnnotationAwareAspectJAutoProxyCreator.puml
new file mode 100644
index 000000000000..01401ba37fe5
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/AnnotationAwareAspectJAutoProxyCreator.puml
@@ -0,0 +1,59 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **AnnotationAwareAspectJAutoProxyCreator 继承体系及关键方法**
+
+interface BeanPostProcessor {
+ + postProcessBeforeInitialization(Object bean, String beanName): Object
+ + postProcessAfterInitialization(Object bean, String beanName): Object
+}
+
+interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
+ + postProcessBeforeInstantiation(Class>, String beanName): Object
+ + postProcessAfterInstantiation(Object bean, String beanName): boolean
+ + postProcessProperties(PropertyValues, Object bean, String beanName): PropertyValues
+ + postProcessPropertyValues(PropertyValues, PropertyDescriptor[], Object bean, String beanName): PropertyValues
+}
+
+interface BeanFactoryAware {
+ + setBeanFactory(BeanFactory): void
+}
+interface BeanClassLoaderAware {
+ + setBeanClassLoader(ClassLoader): void
+}
+
+interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
+ + predictBeanType(Class> beanClass, String beanName): Class>
+ + determineCandidateConstructors(Class> beanClass, String beanName): Constructor>[]
+ + getEarlyBeanReference(Object bean, String beanName): Object
+}
+
+class ProxyConfig {
+ + setProxyTargetClass(boolean): void
+ + isProxyTargetClass(): boolean
+ + setOptimize(boolean): void
+ + isOptimize(): boolean
+ + setOpaque(boolean): void
+ + isOpaque(): boolean
+ + setExposeProxy(boolean): void
+ + isExposeProxy(): boolean
+ + setFrozen(boolean): void
+ + isFrozen(): boolean
+}
+
+class ProxyProcessorSupport extends ProxyConfig implements BeanClassLoaderAware, AopInfrastructureBean
+
+abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
+
+class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator
+
+abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator
+
+class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator
+
+class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator
+
+class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator implements BeanNameAware
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
\ No newline at end of file
diff --git a/truman/src/docs/asciidoc/puml/AopProxy.puml b/truman/src/docs/asciidoc/puml/AopProxy.puml
new file mode 100644
index 000000000000..ab14a14ed273
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/AopProxy.puml
@@ -0,0 +1,32 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **AopProxy 相关结构图**
+
+interface AopProxy {
+ + getProxy(): Object
+ + getProxy(classLoader: ClassLoader): Object
+}
+
+class CglibAopProxy implements AopProxy
+class ObjenesisCglibAopProxy extends CglibAopProxy
+
+interface AopProxyFactory {
+ createAopProxy(config: AdvisedSupport): AopProxy
+}
+
+AopProxyFactory o-right-> AopProxy :create
+
+class AdvisedSupport extends ProxyConfig
+
+AopProxyFactory .up.> AdvisedSupport :according to
+
+class DefaultAopProxyFactory implements AopProxyFactory
+
+class JdkDynamicAopProxy implements AopProxy
+
+interface InvocationHandler
+JdkDynamicAopProxy ..|> InvocationHandler
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
\ No newline at end of file
diff --git a/truman/src/docs/asciidoc/puml/ApplicationContext.puml b/truman/src/docs/asciidoc/puml/ApplicationContext.puml
new file mode 100644
index 000000000000..bd628e8769a5
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/ApplicationContext.puml
@@ -0,0 +1,20 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **""ApplicationContext""的组成**
+card ApplicationContext {
+ card AnnotatedBeanDefinitionReader
+ card ClassPathBeanDefinitionScanner
+ card DefaultListableBeanFactory {
+ card dependencyComparator
+ card autowireCandidateResolver
+ }
+}
+
+AnnotatedBeanDefinitionReader -[hidden]-> ClassPathBeanDefinitionScanner
+ClassPathBeanDefinitionScanner -[hidden]-> DefaultListableBeanFactory
+
+dependencyComparator -[hidden]-> autowireCandidateResolver
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
diff --git a/truman/src/docs/asciidoc/puml/ApplicationEvent.puml b/truman/src/docs/asciidoc/puml/ApplicationEvent.puml
new file mode 100644
index 000000000000..42a09d15b7f5
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/ApplicationEvent.puml
@@ -0,0 +1,44 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **Spring 容器内事件发布实现类图**
+
+
+abstract class ApplicationEvent extends EventObject
+note top of EventObject : JDK 内置事件类型
+note top of ApplicationEvent : Spring 容器内\n自定义事件类型
+
+interface ApplicationListener extends EventListener {
+ + onApplicationEvent(E event):void
+}
+
+interface ApplicationEventPublisher {
+ + publishEvent(ApplicationEvent event):void
+ + publishEvent(Object event):void
+}
+interface ApplicationContext extends ApplicationEventPublisher
+
+interface ConfigurableApplicationContext extends ApplicationContext
+
+abstract class AbstractApplicationContext implements ConfigurableApplicationContext {
+ - applicationEventMulticaster:ApplicationEventMulticaster
+}
+
+interface ApplicationEventMulticaster
+
+ApplicationEventMulticaster .right.> ApplicationListener : notify
+
+ApplicationEventMulticaster .up.> ApplicationEvent : publish
+
+ApplicationListener .up.> ApplicationEvent : receive
+
+abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster
+
+class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
+ - taskExecutor:Executor
+}
+
+AbstractApplicationContext *--> ApplicationEventMulticaster
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
\ No newline at end of file
diff --git a/truman/src/docs/asciidoc/puml/BeanDefinition.puml b/truman/src/docs/asciidoc/puml/BeanDefinition.puml
new file mode 100644
index 000000000000..25c53ee70d40
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/BeanDefinition.puml
@@ -0,0 +1,67 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **BeanDefinition 继承体系及关键属性**
+
+
+abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {
+ - attributes: Map
+}
+
+class BeanMetadataAttributeAccessor extends AttributeAccessorSupport implements BeanMetadataElement {
+ - source: Object
+}
+
+interface BeanDefinition extends AttributeAccessor, BeanMetadataElement
+
+abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable {
+ - beanClass: Object
+ - abstractFlag: boolean
+ - lazyInit: Boolean
+ - autowireMode: int
+ - dependencyCheck: int
+ - dependsOn: String[]
+ - autowireCandidate: boolean
+ - primary: boolean
+ - qualifiers: Map
+ - instanceSupplier: Supplier>
+ - nonPublicAccessAllowed: boolean
+ - lenientConstructorResolution: boolean
+ - factoryBeanName: String
+ - factoryMethodName: String
+ - constructorArgumentValues: ConstructorArgumentValues
+ - propertyValues: MutablePropertyValues
+ - methodOverrides: MethodOverrides
+ - initMethodName: String
+ - destroyMethodName: String
+ - enforceInitMethod: boolean
+ - enforceDestroyMethod: boolean
+ - synthetic: boolean
+ - role: int
+ - description: String
+ - resource: Resource
+}
+
+class RootBeanDefinition extends AbstractBeanDefinition
+
+interface AnnotatedBeanDefinition extends BeanDefinition
+
+class ChildBeanDefinition extends AbstractBeanDefinition {
+ - parentName: String
+}
+
+class GenericBeanDefinition extends AbstractBeanDefinition {
+ - parentName: String
+}
+
+class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
+ - metadata: AnnotationMetadata
+}
+
+class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
+ - metadata: AnnotationMetadata
+ - factoryMethodMetadata: MethodMetadata
+}
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
diff --git a/truman/src/docs/asciidoc/puml/BeanFactory-getBean.puml b/truman/src/docs/asciidoc/puml/BeanFactory-getBean.puml
new file mode 100644
index 000000000000..9e3a63e1bcf7
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/BeanFactory-getBean.puml
@@ -0,0 +1,23 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **BeanFactory.getBean Bean 创建**
+
+actor Actor
+participant BeanFactory << (C,#ADD1B2) >>
+participant BeanPostProcessor << (I,#AB9DE1) >>
+
+Actor -> BeanFactory: getBean
+activate BeanFactory
+
+ BeanFactory -> BeanPostProcessor
+ activate BeanPostProcessor
+
+ BeanFactory <- BeanPostProcessor
+ deactivate BeanPostProcessor
+
+Actor -> BeanFactory
+deactivate BeanFactory
+
+footer D瓜哥 · ""https://www.diguage.com"" · 出品
+@enduml
diff --git a/truman/src/docs/asciidoc/puml/BeanFactory.puml b/truman/src/docs/asciidoc/puml/BeanFactory.puml
new file mode 100644
index 000000000000..0cf0c77e31aa
--- /dev/null
+++ b/truman/src/docs/asciidoc/puml/BeanFactory.puml
@@ -0,0 +1,96 @@
+@startuml
+header D瓜哥 · ""https://www.diguage.com""
+
+title **BeanFactory 继承体系及关键属性**
+
+interface BeanDefinitionRegistry extends AliasRegistry
+
+class SimpleAliasRegistry implements AliasRegistry {
+ - aliasMap: Map
+}
+
+class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
+ - singletonObjects: Map
+ - singletonFactories: Map>
+ - earlySingletonObjects: Map
+ - registeredSingletons: Set
+ - singletonsCurrentlyInCreation: Set
+ - inCreationCheckExclusions: Set
+ - suppressedExceptions: Set
+ - singletonsCurrentlyInDestruction: boolean
+ - disposableBeans: Map
+ - containedBeanMap: Map>
+ - dependentBeanMap: Map>
+ - dependenciesForBeanMap: Map>
+}
+
+abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
+ - factoryBeanObjectCache: Map
+}
+
+interface ListableBeanFactory extends BeanFactory
+
+'StaticListableBeanFactory 不常用,不予展示
+'class StaticListableBeanFactory implements ListableBeanFactory
+
+interface HierarchicalBeanFactory extends BeanFactory
+
+interface ApplicationContext extends ListableBeanFactory, HierarchicalBeanFactory
+
+interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry
+
+interface AutowireCapableBeanFactory extends BeanFactory
+
+interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory
+
+abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
+ - parentBeanFactory: BeanFactory
+ - beanClassLoader: ClassLoader
+ - tempClassLoader: ClassLoader
+ - beanExpressionResolver: BeanExpressionResolver
+ - conversionService: ConversionService
+ - propertyEditorRegistrars: Set
+ - customEditors: Map, Class extends PropertyEditor>>
+ - typeConverter: TypeConverter
+ - embeddedValueResolvers: List
+ - beanPostProcessors: List
+ - beanPostProcessorCache: BeanPostProcessorCache
+ - scopes: Map
+ - mergedBeanDefinitions: Map
+ - alreadyCreated: Set
+ - prototypesCurrentlyInCreation: ThreadLocal