设计模式理解

设计模式理解

七大设计原则

通过理解七大设计原则,来告诉程序员如何进行面向对象的设计

  • 开闭原则:对修改关闭,对扩展开放。一切都是为了保证代码的扩展性和复用性。而开闭原则是基础要求。
  • 单一职责原则:单类应该如何定义
  • 接口隔离原则:单接口应该如何定义
  • 依赖倒置原则:面向接口/抽象编程思维,再方法的返回值,参数类型等都室友接口或者抽象类,而不是使用实现类。
  • 里氏替换原则:如何去编写继承类的代码,子类不用去覆盖父类已经实现的方法(抽象模板方法)
  • 迪米特法则:最少认知原则,不要和陌生人说话,类与类之间要高内聚,低耦合。
    • 项目经历不要之间去访问与他没有直接关系的测试任意。而是调用测试经历的相关功能
  • 合成复用原则:能用组合,聚合关系的情况,不要使用继承关系。就比如说,如果你想拥有某个对象的功能,不用直接继承他,而是将他作为我的成员变量去使用。
二十三种设计模式
  • 创建型设计模式:简单工厂模式,工厂方法模式,抽象工厂模式,单例模式,原型模式,构建者模式。
  • 行为型设计模式:责任链模式,观察者模式,门面模式,策略模式,适配器模式等
  • 结构型设计模式:组合模式,代理模式,装饰模式等。
Spring重要接口详解

BeanFactory继承体系

Mybatis设计分析:

  • SqlSessionFactory
  • SqlSession
  • Executor

这时BeanFactory基本的类体系接口,这里没有包括强大的ApplicationContext体系

四级接口继承体系:
  1. BeanFactory作为一个主接口不继承任何接口,暂且称为一级接口
  2. AutowireCapableBeanFactory、HierarchicalBeanFactory、ListableBeanFactory3个子接口继承了它,进行功能上的增强,这三个子接口称为二级接口。
  3. ConfigurableBeanFactory可以被称为三级接口,对二级接口HierarchicalBeanFactory进行了再次增强,它还继承了另一个外来的接口SingletonBeanRegistry
  4. ConfigurableListableBeanFactory是一个更强大的接口,继承了上述的所有接口,无所不包,称为四级接口

总结:

  1. BeanFactory是Spring bean容器的根接口
    提供获取bean,是否包含bean,是否单例与原先,获取bean类型,bean别名的api。
  2. AutowireCapableBeanFactory提供工厂的装配功能。
  3. HieracalBeanFactory提供父容器的访问功能
  4. ConfigurableBeanFactory如名,提供factory的配置功能,眼花缭乱好多api
  5. ConfigurableListableBeanFactory集大成者,提供解析,修改bean定义,并初始化单例
  6. ListableBeanFactory提供容器内bean实例的枚举功能。这边不会考虑父容器内的实例。

设计模式原则里的接口隔离原则

下面是继承关系的2个抽象类和实现类

  1. AbstractBeanFactory作为一个抽象类,实现了三级接口ConfigurableBeanFactory大部分功能
  2. AbstractAutowireCapableBeanFactory同样是抽象类,继承自AbstractBeanFactory,并额外实现了二级接口AutowireCapableBeanFactory
  3. DefaultListableBeanFactory继承自AbstractAutowireCapableBeanFactory,实现了最大的四级接口ConfigurableListableBeanFactory,并实现了一个外来接口BeanDefinitionRegistry,它并非抽象类
  4. 最后是最强大的XmlBeanFactory,继承自DefaultListableBeanFactory,重写了一些功能,使自己更强大。

总结:BeanFactory的类体系结构看似繁杂混乱,实际上由上而下井井有条,非常容易理解。

BeanFactory
package org.springframework.beans.factory;
public interface BeanFactory {
 //⽤来引⽤⼀个实例,或把它和⼯⼚产⽣的Bean区分开
 //就是说,如果⼀个FactoryBean的名字为a,那么,&a会得到那个Factory
 String FACTORY_BEAN_PREFIX = "&";
 /*
 * 四个不同形式的getBean⽅法,获取实例
 */
Object getBean(String name) throws BeansException;
 <T> T getBean(String name, Class<T> requiredType) throws BeansException;
 <T> T getBean(Class<T> requiredType) throws BeansException;
 Object getBean(String name, Object... args) throws BeansException;
 // 是否存在
 boolean containsBean(String name);
 // 是否为单实例
 boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
 // 是否为原型(多实例)
 boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
 // 名称、类型是否匹配
 boolean isTypeMatch(String name, Class<?> targetType)
 throws NoSuchBeanDefinitionException;
 // 获取类型
 Class<?> getType(String name) throws NoSuchBeanDefinitionException;
 // 根据实例的名字获取实例的别名
 String[] getAliases(String name);
}
  • 源码说明:
    • 4个判断实例的方法。getBean的重载方法。
    • 4个判断的方法。判断是否存在,是否为单例、原型,名称类型是否匹配。
    • 1个获取类型的方法、一个获取别名的方法。根据名称获取类型、根据名称获取别名。一目了然
  • 总结:
    • 这10个方法,很明显,这是一个典型的工厂模式的工厂接口。
ListableBeanFactory

可将Bean逐一列出的工厂。

public interface ListableBeanFactory extends BeanFactory {
 // 对于给定的名字是否含有
 boolean containsBeanDefinition(String beanName); BeanDefinition
 // 返回⼯⼚的BeanDefinition总数
 int getBeanDefinitionCount();
 // 返回⼯⼚中所有Bean的名字
 String[] getBeanDefinitionNames();
 // 返回对于指定类型Bean(包括⼦类)的所有名字
 String[] getBeanNamesForType(Class<?> type);
 /*
 * 返回指定类型的名字
 * includeNonSingletons为false表示只取单例Bean,true则不是
 * allowEagerInit为true表示⽴刻加载,false表示延迟加载。
* 注意:FactoryBeans都是⽴刻加载的。
 */
 String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons,
 boolean allowEagerInit);
 // 根据类型(包括⼦类)返回指定Bean名和Bean的Map
 <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
 <T> Map<String, T> getBeansOfType(Class<T> type,
 boolean includeNonSingletons, boolean allowEagerInit)
 throws BeansException;
 // 根据注解类型,查找所有有这个注解的Bean名和Bean的Map
 Map<String, Object> getBeansWithAnnotation(
 Class<? extends Annotation> annotationType) throws BeansException;
 // 根据指定Bean名和注解类型查找指定的Bean
 <A extends Annotation> A findAnnotationOnBean(String beanName,
 Class<A> annotationType);
}

  • 源码说明:
    • 3个跟BeanDefinition有关的总体操作。包括BeanDefinition的总数、名字的集合、指定类型的名字的集合。
      • 这里指出,BeanDefinition是Spring种非常重要的一个类,每个BeanDefinition实例都包含一个类再Spring工厂中所有属性。
    • 2个getBeanNamesForType重载方法。根据指定类型(包括子类)获取其对应的所有Bean名字
    • 2个getBeanOfType重载方法。根据类型(包括子类)返回指定Bean名和Bean的Map。
    • 2个getBeansOfType重载方法。根据类型(包括子类)返回指定Bean名和Bean的Map.
    • 2个跟注解查找有关的方法。根据注解类型,查找Bean名和Bean的Map。以及根据指定Bean名和注解类型查找指定的Bean。
  • 总结:
    正如这个工厂接口的名字,这个工厂接口最大的特点就是可以列出工厂可以生产的所有实例。当然,工厂并没有直接提供返回所有实例的方法,也没这个必要,它可以返回指定类型的所有的实例。而且你可以通过getBeanDefinitionNames()得到工厂所有bean的名字,然后根据这些名字得到所有的Bean。这个工厂接口扩展了BeanFactory的功能,作为上文指出的BeanFactory二级接口,有9个独有的方法,扩展了跟BeanDefinition的功能,提供了BeanDefinition、BeanName、注解有关的各种操作。它可以根据条件返回Bean的集合,这就是它名字的由来–ListableBeanFactory.
HierarchicalBeanFactory

分层的Bean工厂

public interface HierarchicalBeanFactory extends BeanFactory {
 // 返回本Bean⼯⼚的⽗⼯⼚
 BeanFactory getParentBeanFactory(); 
 // 本地⼯⼚是否包含这个Bean
 boolean containsLocalBean(String name); 
}
  • 参数说明:
    • 第一个方法返回本Bean工厂的父工厂。这个方法实现了工厂的分层。
    • 第二个方法判断本地工厂是否包含这个Bean(忽略其他所有父工厂)。这也是分层思想的体现。
  • 总结:
    这个工厂接口非常简单,实现了Bean工厂的分层。这个工厂接口也是继承自BeanFactory,也是一个二级接口,相对于父接口,它只扩展了一个重要的功能–工厂分层。
AutowireCapableBeanFactory

自动装配的Bean工厂

public interface AutowireCapableBeanFactory extends BeanFactory {
 // 这个常量表明⼯⼚没有⾃动装配的Bean
 int AUTOWIRE_NO = 0; 
 // 表明根据名称⾃动装配
 int AUTOWIRE_BY_NAME = 1; 
 // 表明根据类型⾃动装配
 int AUTOWIRE_BY_TYPE = 2; 
 // 表明根据构造⽅法快速装配
 int AUTOWIRE_CONSTRUCTOR = 3; 
 //表明通过Bean的class的内部来⾃动装配(有没翻译错...)Spring3.0被弃⽤。
 @Deprecated
 int AUTOWIRE_AUTODETECT = 4; 
 // 根据指定Class创建⼀个全新的Bean实例
 <T> T createBean(Class<T> beanClass) throws BeansException; 
 // 给定对象,根据注释、后处理器等,进⾏⾃动装配
 void autowireBean(Object existingBean) throws BeansException; 
 // 根据Bean名的BeanDefinition装配这个未加⼯的Object,执⾏回调和各种后处理器。
 Object configureBean(Object existingBean, String beanName) throws
BeansException;
 // 分解Bean在⼯⼚中定义的这个指定的依赖descriptor
 Object resolveDependency(DependencyDescriptor descriptor, String beanName)
throws BeansException;
 // 根据给定的类型和指定的装配策略,创建⼀个新的Bean实例
 Object createBean(Class<?> beanClass, int autowireMode, boolean
dependencyCheck) throws BeansException;
// 与上⾯类似,不过稍有不同。
 Object autowire(Class<?> beanClass, int autowireMode, boolean
dependencyCheck) throws BeansException;
 /*
 * 根据名称或类型⾃动装配
 */
 void autowireBeanProperties(Object existingBean, int autowireMode, boolean
dependencyCheck)
 throws BeansException;
 /*
 * 也是⾃动装配
 */
 void applyBeanPropertyValues(Object existingBean, String beanName) throws
BeansException;
 /*
 * 初始化⼀个Bean...
 */
 Object initializeBean(Object existingBean, String beanName) throws
BeansException;
 /*
 * 初始化之前执⾏BeanPostProcessors
 */
 Object applyBeanPostProcessorsBeforeInitialization(Object existingBean,
String beanName)
 throws BeansException;
 /*
 * 初始化之后执⾏BeanPostProcessors
 */
 Object applyBeanPostProcessorsAfterInitialization(Object existingBean,
String beanName)
 throws BeansException;
 /*
 * 分解指定的依赖
 */
 Object resolveDependency(DependencyDescriptor descriptor, String beanName,
 Set<String> autowiredBeanNames, TypeConverter typeConverter) throws
BeansException;
}

源码说明:
  1. 总共5个今天不可变常量来指明装配策略,其中一个常量被spring3.0废弃,一个常量表示没有自动装配,另外3个常量指明不同的装配策略–根据名称、根据类型、根据构造方法。
  2. 8个跟自动装配有关的方法,实在是繁杂。
  3. 2个执行BeanPostProcessors的方法
  4. 2个分解指定依赖的方法

总结:这个工厂接口继承自BeanFactory,它扩展了自动装配的功能,根据类定义BeanDefinition装配Bean,执行前,后处理器等。

ConfigurableBeanFactory

复杂的配置Bean工厂

public interface ConfigurableBeanFactory extends HierarchicalBeanFactory,
SingletonBeanRegistry {
 String SCOPE_SINGLETON = "singleton"; // 单例
 String SCOPE_PROTOTYPE = "prototype"; // 原型
 /*
 * 搭配HierarchicalBeanFactory接⼝的getParentBeanFactory⽅法
 */
 void setParentBeanFactory(BeanFactory parentBeanFactory) throws
IllegalStateException;
 /*
 * 设置、返回⼯⼚的类加载器
 */
 void setBeanClassLoader(ClassLoader beanClassLoader);
 ClassLoader getBeanClassLoader();
 /*
 * 设置、返回⼀个临时的类加载器
 */
 void setTempClassLoader(ClassLoader tempClassLoader);
 ClassLoader getTempClassLoader();
 /*
 * 设置、是否缓存元数据,如果false,那么每次请求实例,都会从类加载器重新加载(热加载)
 */
 void setCacheBeanMetadata(boolean cacheBeanMetadata);
 
 boolean isCacheBeanMetadata();//是否缓存元数据
/*
 * Bean表达式分解器
 */
 void setBeanExpressionResolver(BeanExpressionResolver resolver);
 
 BeanExpressionResolver getBeanExpressionResolver();
 /*
 * 设置、返回⼀个转换服务
 */
 void setConversionService(ConversionService conversionService);
 ConversionService getConversionService();
 /*
 * 设置属性编辑登记员...
 */
 void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
 /*
 * 注册常⽤属性编辑器
 */
 void registerCustomEditor(Class<?> requiredType, Class<? extends
PropertyEditor> propertyEditorClass);
 /*
 * ⽤⼯⼚中注册的通⽤的编辑器初始化指定的属性编辑注册器
 */
 void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
 /*
 * 设置、得到⼀个类型转换器
 */
 void setTypeConverter(TypeConverter typeConverter);
 TypeConverter getTypeConverter();
 /*
 * 增加⼀个嵌⼊式的StringValueResolver
 */
 void addEmbeddedValueResolver(StringValueResolver valueResolver);
 String resolveEmbeddedValue(String value);//分解指定的嵌⼊式的值
 void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);//设置⼀个
Bean后处理器
 int getBeanPostProcessorCount();//返回Bean后处理器的数量
 void registerScope(String scopeName, Scope scope);//注册范围
 String[] getRegisteredScopeNames();//返回注册的范围名
 Scope getRegisteredScope(String scopeName);//返回指定的范围
 AccessControlContext getAccessControlContext();//返回本⼯⼚的⼀个安全访问上下⽂
 void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);//从其他的⼯
⼚复制相关的所有配置
 /*
 * 给指定的Bean注册别名
 */
 void registerAlias(String beanName, String alias) throws
BeanDefinitionStoreException;
 void resolveAliases(StringValueResolver valueResolver);//根据指定的
StringValueResolver移除所有的别名
 /*
 * 返回指定Bean合并后的Bean定义
 */
 BeanDefinition getMergedBeanDefinition(String beanName) throws
NoSuchBeanDefinitionException;
 boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;//
判断指定Bean是否为⼀个⼯⼚Bean
 void setCurrentlyInCreation(String beanName, boolean inCreation);//设置⼀个
Bean是否正在创建
 boolean isCurrentlyInCreation(String beanName);//返回指定Bean是否已经成功创建
 void registerDependentBean(String beanName, String dependentBeanName);//注册
⼀个依赖于指定bean的Bean
 String[] getDependentBeans(String beanName);//返回依赖于指定Bean的所欲Bean名
 String[] getDependenciesForBean(String beanName);//返回指定Bean依赖的所有Bean
名
 void destroyBean(String beanName, Object beanInstance);//销毁指定的Bean
 void destroyScopedBean(String beanName);//销毁指定的范围Bean
 void destroySingletons(); //销毁所有的单例类
}
ConfigurableListableBeanFactory

BeanFactory的接口集大成者

public interface ConfigurableListableBeanFactory
 extends ListableBeanFactory, AutowireCapableBeanFactory,
ConfigurableBeanFactory {
 void ignoreDependencyType(Class<?> type);//忽略⾃动装配的依赖类型
 void ignoreDependencyInterface(Class<?> ifc);//忽略⾃动装配的接⼝
 /*
 * 注册⼀个可分解的依赖
 */
 void registerResolvableDependency(Class<?> dependencyType, Object
autowiredValue);
 /*
 * 判断指定的Bean是否有资格作为⾃动装配的候选者
 */
 boolean isAutowireCandidate(String beanName, DependencyDescriptor
descriptor) throws NoSuchBeanDefinitionException;
 // 返回注册的Bean定义
 BeanDefinition getBeanDefinition(String beanName) throws
NoSuchBeanDefinitionException;
 // 暂时冻结所有的Bean配置
 void freezeConfiguration();
 // 判断本⼯⼚配置是否被冻结
 boolean isConfigurationFrozen();
 // 使所有的⾮延迟加载的单例类都实例化。
 void preInstantiateSingletons() throws BeansException;
}

  • 源码说明:
    1. 2个忽略自动装配的方法。
    2. 1个注册可分解依赖的方法。
    3. 1个判断指定的Bean是否有资格作为自动装配的候选者的方法。
    4. 1个根据指定bean名,返回注册的Bean定义的方法。
    5. 2个冻结所有的Bean配置相关的方法。
    6. 1个使所有的非延迟加载的单例类都实例化的方法。
  • 总结:
    工厂接口ConfigurableListableBeanFactory同时继承了3个接口,ListableBeanFactory、AutowireCapableBeanFactory和ConfigurableBeanFactory,扩展之后,加上自有的这8个方法,这个工厂接口总共有83个方法,实在是巨大到不行。这个工厂接口的自有方法总体上只是对父类接口功能的补充,包含了BeanFactory体系目前的所有方法,可以说是接口的集大成者。
BeanDefinitionRegistry

额外的接口,这个接口基本用来操作定义再工厂内部的BeanDefinition的。

public interface BeanDefinitionRegistry extends AliasRegistry {
 // 给定bean名称,注册⼀个新的bean定义
 void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
 /*
 * 根据指定Bean名移除对应的Bean定义
 */
 void removeBeanDefinition(String beanName) throws
NoSuchBeanDefinitionException;
 /*
 * 根据指定bean名得到对应的Bean定义
 */
 BeanDefinition getBeanDefinition(String beanName) throws
NoSuchBeanDefinitionException;
 /*
 * 查找,指定的Bean名是否包含Bean定义
 */
 boolean containsBeanDefinition(String beanName);
 String[] getBeanDefinitionNames();//返回本容器内所有注册的Bean定义名称
 int getBeanDefinitionCount();//返回本容器内注册的Bean定义数⽬
 boolean isBeanNameInUse(String beanName);//指定Bean名是否被注册过。
}

Spring容器初始化流程源码分析


找入口:一般就是调用第三方框架的时候,这个地方就是入口
主流程源码分析
找入口
  • java程序入口

    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
    
  • web程序入口

    <context-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>classpath:spring.xml</param-value>
    </context-param>
    <listener>
     <listener-class>
     org.springframework.web.context.ContextLoaderListener
     </listener-class>
    </listener>
    

    主要:不管上面哪种方式,最终都会调用AbstractApplicationContext的refersh方法,而这个方法才是真正的入口。

流程解析
  • AbstractApplicationContext的refresh方法

    public void refresh() throws BeansException, IllegalStateException {
     synchronized (this.startupShutdownMonitor) {
     // Prepare this context for refreshing.
     // STEP 1: 刷新预处理
     prepareRefresh();
     // Tell the subclass to refresh the internal bean factory.
     // STEP 2:
     // a) 创建IoC容器(DefaultListableBeanFactory)
     // b) 加载解析XML⽂件(最终存储到Document对象中)
     // c) 读取Document对象,并完成BeanDefinition的加载和注册⼯作
     ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    // Prepare the bean factory for use in this context.
     // STEP 3: 对IoC容器进⾏⼀些预处理(设置⼀些公共属性)
     prepareBeanFactory(beanFactory);
     try {
     // Allows post-processing of the bean factory in context subclasses.
     // STEP 4:
     postProcessBeanFactory(beanFactory);
     // Invoke factory processors registered as beans in the context.
     // STEP 5: 调⽤BeanFactoryPostProcessor后置处理器对BeanDefinition处理
     invokeBeanFactoryPostProcessors(beanFactory);
     // Register bean processors that intercept bean creation.
     // STEP 6: 注册BeanPostProcessor后置处理器
     registerBeanPostProcessors(beanFactory);
     // Initialize message source for this context.
     // STEP 7: 初始化⼀些消息源(⽐如处理国际化的i18n等消息源)
     initMessageSource();
     // Initialize event multicaster for this context.
     // STEP 8: 初始化应⽤事件⼴播器
     initApplicationEventMulticaster();
     // Initialize other special beans in specific context subclasses.
     // STEP 9: 初始化⼀些特殊的bean
     onRefresh();
     // Check for listener beans and register them.
     // STEP 10: 注册⼀些监听器
     registerListeners();
     // Instantiate all remaining (non-lazy-init) singletons.
     // STEP 11: 实例化剩余的单例bean(⾮懒加载⽅式)
     // 注意事项:Bean的IoC、DI和AOP都是发⽣在此步骤
     finishBeanFactoryInitialization(beanFactory);
     // Last step: publish corresponding event.
     // STEP 12: 完成刷新时,需要发布对应的事件
     finishRefresh();
     }
     catch (BeansException ex) {
     if (logger.isWarnEnabled()) {
     logger.warn("Exception encountered during context initialization - "
    +
     "cancelling refresh attempt: " + ex);
     }
    // Destroy already created singletons to avoid dangling resources.
     destroyBeans();
     // Reset 'active' flag.
     cancelRefresh(ex);
     // Propagate exception to caller.
     throw ex;
     }
     finally {
     // Reset common introspection caches in Spring's core, since we
     // might not ever need metadata for singleton beans anymore...
     resetCommonCaches();
     }
     }
     }
    
    创建BeanFactory流程源码分析
    找入口

    AbstractApplicationContext类的refresh方法:

    // Tell the subclass to refresh the internal bean factory.
    // STEP 2:
    // a) 创建IoC容器(DefaultListableBeanFactory)
    // b) 加载解析XML⽂件(最终存储到Document对象中)
    // c) 读取Document对象,并完成BeanDefinition的加载和注册⼯作
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
    
流程解析
  • 进入AbstractApplication的obtainFreshBeanFactory方法:
    用于创建一个新的IOC容器,这个IOC容器就是DefaultListableBeanFactory对象。

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
     // 主要是通过该⽅法完成IoC容器的刷新
     refreshBeanFactory();
     ConfigurableListableBeanFactory beanFactory = getBeanFactory();
     if (logger.isDebugEnabled()) {
     logger.debug("Bean factory for " + getDisplayName() + ": " +
    beanFactory);
     }
     return beanFactory;
     }
    
  • 进入AbstractRefreshableApplicationContext的refreshBeanFactory方法:

    • 销毁以前的容器
    • 创建新的IOC容器
    • 加载BeanDefinition对象注册到IOC容器中
protected final void refreshBeanFactory() throws BeansException {
 // 如果之前有IoC容器,则销毁
 if (hasBeanFactory()) {
 destroyBeans();
 closeBeanFactory();
 }
 try {
 // 创建IoC容器,也就是DefaultListableBeanFactory
 DefaultListableBeanFactory beanFactory = createBeanFactory();
 beanFactory.setSerializationId(getId());
 customizeBeanFactory(beanFactory);
 // 加载BeanDefinition对象,并注册到IoC容器中(重点)
 loadBeanDefinitions(beanFactory);
 synchronized (this.beanFactoryMonitor) {
 this.beanFactory = beanFactory;
 }
 }
 catch (IOException ex) {
 throw new ApplicationContextException("I/O error parsing bean definition
source for " + getDisplayName(), ex);
 }
 }
  • 进入AbstractRefreshableApplicationContext的createBeanFactory方法
 protected DefaultListableBeanFactory createBeanFactory() {
 return new DefaultListableBeanFactory(getInternalParentBeanFactory());
 }
加载BeanDefinition流程分析
找入口

AbstractRefreshableApplicationContext类的refreshBeanFactory方法中第13行代码:

protected final void refreshBeanFactory() throws BeansException {
 // 如果之前有IoC容器,则销毁
 if (hasBeanFactory()) {
 destroyBeans();
 closeBeanFactory();
 }
 try {
 // 创建IoC容器,也就是DefaultListableBeanFactory
 DefaultListableBeanFactory beanFactory = createBeanFactory();
 beanFactory.setSerializationId(getId());
 customizeBeanFactory(beanFactory);
 // 加载BeanDefinition对象,并注册到IoC容器中(重点)
 loadBeanDefinitions(beanFactory);
 synchronized (this.beanFactoryMonitor) {
 this.beanFactory = beanFactory;
 }
 }
 catch (IOException ex) {
 throw new ApplicationContextException("I/O error parsing bean definition
source for " + getDisplayName(), ex);
 }
 }
流程相关类的说明
  • AbstractRefreshableApplicationContext
    主要用来对BeanFactory提供refresh功能。包括BeanFactory的创建和BeanDefinition的定义,解析,注册操作。
  • AbstractXmlApplicationContext
    主要提供对于XML资源的加载功能。包括从Resource资源对象和资源路径中加载XML文件。
  • AbstractBeanDefinitionReader
    主要提供对于BeanDefinition对象的读取功能。具体读取工作交给子类实现。
  • XmlBeanDefinitionReader
    主要通过DOM4J对于XML资源的读取,解析功能,并提供对于BeanDefinition的注册功能。
  • DefaultBeanDefinitionDocumentReader
  • BeanDefinitionParserDelegate
流程解析
  • 进入AbstractXmlApplicationContext的loadBeanDefinitions方法:
    • 创建一个XmlBeanDefinitionReader,通过阅读XML文件,真正完成BeanDefinitiond加载和注册
    • 配置XmlBeanDefinitionReader并进行初始化
    • 委托给XmlBeanDefinitionReader去加载BeanDefinition.
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException {
 // Create a new XmlBeanDefinitionReader for the given BeanFactory.
 // 给指定的⼯⼚创建⼀个BeanDefinition阅读器
 // 作⽤:通过阅读XML⽂件,真正完成BeanDefinition的加载和注册
 XmlBeanDefinitionReader beanDefinitionReader = new 
XmlBeanDefinitionReader(beanFactory);
 // Configure the bean definition reader with this context's
 // resource loading environment.
 beanDefinitionReader.setEnvironment(this.getEnvironment());
 beanDefinitionReader.setResourceLoader(this);
 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
 // Allow a subclass to provide custom initialization of the reader,
 // then proceed with actually loading the bean definitions.
 initBeanDefinitionReader(beanDefinitionReader);
 
 // 委托给BeanDefinition阅读器去加载BeanDefinition
 loadBeanDefinitions(beanDefinitionReader);
 }
 protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws
BeansException, IOException {
 // 获取资源的定位
 // 这⾥getConfigResources是⼀个空实现,真正实现是调⽤⼦类的获取资源定位的⽅法
 // ⽐如:ClassPathXmlApplicationContext中进⾏了实现
 // ⽽FileSystemXmlApplicationContext没有使⽤该⽅法
 Resource[] configResources = getConfigResources();
 if (configResources != null) {
 // XML Bean读取器调⽤其⽗类AbstractBeanDefinitionReader读取定位的资源
 reader.loadBeanDefinitions(configResources);
 }
 // 如果⼦类中获取的资源定位为空,则获取FileSystemXmlApplicationContext构造⽅法中
setConfigLocations⽅法设置的资源
 String[] configLocations = getConfigLocations();
 if (configLocations != null) {
 // XML Bean读取器调⽤其⽗类AbstractBeanDefinitionReader读取定位的资源
 reader.loadBeanDefinitions(configLocations);
 }
 }
  • loadBeanDefinitions方法经过一路的兜兜转转,最终来到了XmlBeanDefinitionReader的doLoadBeanDefinitions方法:
    • 一个是对XML文件进行DOM解析;
    • 一个是完成BeanDefinition对象的加载与注册。
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
 throws BeanDefinitionStoreException {
 try {
 // 通过DOM4J加载解析XML⽂件,最终形成Document对象
 Document doc = doLoadDocument(inputSource, resource);
 // 通过对Document对象的操作,完成BeanDefinition的加载和注册⼯作
 return registerBeanDefinitions(doc, resource);
 }
 //省略⼀些catch语句
 catch (Throwable ex) {
 ......
 }
 }

  • 此次我们暂不处理DOM4J加载解析XML的流程,我们重点分析BeanDefinition的加载注册流程
  • 进入XmlBeanDefinitionReader的registerBeanDefinitions方法:
    • 创建DefaultBeanDefinitionDocumentReader用来解析Document对象。
    • 获得容器已注册的BeanDefinition数量
    • 委托给DefaultBeanDefinitionDocumentReader来完成BeanDefinition的加载,注册工作
    • 统计新注册的BeanDefinition数量
public int registerBeanDefinitions(Document doc, Resource resource) throws
 BeanDefinitionStoreException {
 // 创建DefaultBeanDefinitionDocumentReader⽤来解析Document对象
 BeanDefinitionDocumentReader documentReader =
 createBeanDefinitionDocumentReader();
 // 获得容器中注册的Bean数量
 int countBefore = getRegistry().getBeanDefinitionCount();
 //解析过程⼊⼝,BeanDefinitionDocumentReader只是个接⼝
 //具体的实现过程在DefaultBeanDefinitionDocumentReader完成
 documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
 // 统计注册的Bean数量
 return getRegistry().getBeanDefinitionCount() - countBefore;
 }
  • 进入DefaultBeanDefinitionDocumentReader的registerBeanDefinitions方法:
    • 获得Document的根元素标签
    • 真正实现BeanDefinition解析和注册工作
public void registerBeanDefinitions(Document doc, XmlReaderContext
readerContext
 {
 this.readerContext = readerContext;
 logger.debug("Loading bean definitions");
 // 获得Document的根元素<beans>标签
 Element root = doc.getDocumentElement();
 // 真正实现BeanDefinition解析和注册⼯作
 doRegisterBeanDefinitions(root);
 }

  • 进入DefaultBeanDefinitionDocumentReader doRegisterBeanDefinitions方法:
    • 这里使用了委托模式,将具体的BeanDefinition解析工作交给了BeanDefinitionParserDelegate去完成
    • 再解析Bean定义之前,进行自定义的解析,增强解析过程的可扩展性
    • 委托给BeanDefinitionParseDelegate,从Document的根元素开始进行BeanDefinition的解析
    • 再解析Bean定义之后,进行自定义的解析,增加解析过程的可扩展性
protected void doRegisterBeanDefinitions(Element root) {
 // Any nested <beans> elements will cause recursion in this method. In
 // order to propagate and preserve <beans> default-* attributes correctly,
 // keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback
purposes,
 // then ultimately reset this.delegate back to its original (parent)
reference.
 // this behavior emulates a stack of delegates without actually
necessitating one.
 
 // 这⾥使⽤了委托模式,将具体的BeanDefinition解析⼯作交给了
BeanDefinitionParserDelegate去完成
 BeanDefinitionParserDelegate parent = this.delegate;
 this.delegate = createDelegate(getReaderContext(), root, parent);
 if (this.delegate.isDefaultNamespace(root)) {
 String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
 if (StringUtils.hasText(profileSpec)) {
 String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
 profileSpec,
BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
 if
(!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
 if (logger.isInfoEnabled()) {
 logger.info("Skipped XML bean definition file due to specified
profiles [" + profileSpec +
 "] not matching: " + getReaderContext().getResource());
 }
 return;
 }
 }
 }
 // 在解析Bean定义之前,进⾏⾃定义的解析,增强解析过程的可扩展性
 preProcessXml(root);
 // 委托给BeanDefinitionParserDelegate,从Document的根元素开始进⾏BeanDefinition
的解析
 parseBeanDefinitions(root, this.delegate);
 // 在解析Bean定义之后,进⾏⾃定义的解析,增加解析过程的可扩展性
 postProcessXml(root);
 this.delegate = parent;
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值