spring知识总结

加载机制:

ClassPathXmlApplicationContext:应用程序的上下文,将普通路径解析为类(classpath)路径资源名称

         // 多个配置文件的情况下,后加载的bean会覆盖先前定义好的bean,这样做的目的是为了通过额外的XML文件来特意重写某个Bean

         public ClassPathXmlApplicationContext(String[] configLocations, booleanrefresh, ApplicationContext parent)

                 throwsBeansException {

         //

         super(parent);

         // 解析 bean.xml 文件

         setConfigLocations(configLocations);

         if (refresh){

                 refresh();

         }

}

 

DefaultBeanDefinitionDocumentReader BeanDefinitionDocumentReader 接口的默认实现根据spring-beans” DTDXSD格式读取bean定义Spring的默认XML bean定义格式)。

        

         // {@code <beans />} 元素中注册每个定义好的bean

         // 同时会解析 beans profile

         -> protectedvoid doRegisterBeanDefinitions(Element root);

        

         // 根据spring-beansXSD解析bean定义

         -> public voidregisterBeanDefinitions(Document doc, XmlReaderContextreaderContext);

 

         // 解析 root 节点下的其它节点 import","alias", "bean".

         -> protectedvoid parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate);

        

         -> 判断当前 ele 是什么节点 ,然后在跳转到对应的方法中处理

         private voidparseDefaultElement(Element ele,BeanDefinitionParserDelegate delegate);

                 |

                 |--->processBeanDefinition(ele, delegate);

 

        

 

 

1.InputStreamSource 封装了任何能返回 InputStream 的类,比如 File ClassPath Byte Array

         -> booleanexists(); 判断文件是否存在

         -> booleanisReadable(); 文件是否可读/权限

         -> booleanisOpen(); 文件是否打开状态

         -> 此外还提供了 URL URI File 类型转换,以及获取lastModified属性,文件名,出错信息等

 

 

1.加载 bean.xml 文件

         -> ConfigReader:用于读取及验证配置文件是否正确(XMLXSD验证)

         -> ReflectionUtil:根据 bean.xml 中的配置进行反射实例化对象

 

 

2.解析 bean.xml 标签,找到对应 bean 的配置,实例化对

Spring 核心类

-> DefaultListableBeanFactory(核心类/注册及Bean的默认实现)    扩展了 XmlBeanDefinitionReader(自定义的XML读取器,实现个性化的BeanDefinitionReader读取)

                 ->XmlBeanDefinitionReader XML文件读取

                          ->AbstractBeanDefinitionReader

                                   //读取 bean 定义时的环境  比如  @Profile("dev") 这种 

                                   //同时默认加载systemPropertiessystemEnvironment 系统配置及修通变量  - 详请(StandardEnvironment.class

                                   ->protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry);

                                  

                                   //从指定的XML文件加载bean定义。

                                   publicint loadBeanDefinitions(EncodedResource encodedResource) throwsBeanDefinitionStoreException;

                                  

                                   ->BeanDefinitionReader

                

                          ->ResourceLoader:资源加载器,应用于根据给定资源地址返回对应资源(Resource

                                   ->DefaultResourceLoaderResourceLoader接口的默认实现。

                                            ->AbstractApplicationContext

                                                    //

                                                    ->public void refresh();

                                                   

                                                    ->AbstractRefreshableApplicationContext

                                                            

                                                             *刷新上下文

                                                             *如果之前存在 bean工厂,关闭以前的bean工厂  (destroyBeans() | closeBeanFactory())

                                                             *为上下文生命周期的下一阶段初始化一个新鲜的bean工厂。

                                                             ->protected final void refreshBeanFactory()

                                                                      ->DefaultListableBeanFactory beanFactory = createBeanFactory(); 然后创建一个全新的  BeanFactory

                                                                     

                                                                      ->protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)

                                                            

                                                            

                                                    ->AbstractXmlApplicationContext

                                                             *通过 XmlBeanDefinitionReader 加载定义好的 Bean

                                                             ->protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)

                                                                     

                                                             ->AbstractRefreshableConfigApplicationContext

                                                            

                                                                      *init-param风格设置此应用程序上下文的配置位置,

                                                                      *即用不同的位置用逗号,分号或空格分开。

                                                                      *<p>如果没有设置,则实现可以使用默认值。

                                                                      ->public void setConfigLocations(String... locations)

                                                                     

                         

                          ->AbstractBeanDefinitionRead:实现下面俩个接口

                                   ->BeanDefinitionReader:资源转换 BeanDefinition 的各个功能

                                   ->EnvironmentCapable:获取 Environment 方法

                          ->DocumentLoader:从资源文件加载到转换为 Document 功能

                         

                          —>BeanDefinitionDocumentRead:读取Document并注册 BeanDefinition

                         

                          ->BeanDefinitionParserDelegate:解析 Element 各种方法

                                   //根据 bean元素的属性初始化的bean定义

                                   //解析 Element(比如 <bean />) 会设置 scope  lazy-init ,

                                   //默认属性参考DocumentDefaultsDefinition

                                   ->public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, StringbeanName,BeanDefinition containingBean, AbstractBeanDefinition bd);

                

                

                 ->  继承AbstractAutowireCapableBeanFactory 综合 AbstractBeanFactory 并对接口 Autowire CapableBeanFactory 进行实现

                          // 确定指定 bean 的目标类型

                          ->protected Class<?> determineTargetType(String beanName,RootBeanDefinition mbd, Class<?>... typesToMatch)

                         

 

                          /**

                           * 使用深拷贝来拷贝 bean工厂中正常运行的bean   目的是防止因直接修改引用而导致 bean工厂中维护的 bean对象被修改

                           * @param beanName 为了获得更准确的异常信息而传递的bean名称

                           * @param mbd 合并后的bean

                           * @param bw 使用 BeanWrapper 包装目标对象  bw.setPropertyValues(newMutablePropertyValues(deepCopy));

                           * @param pvs 新的属性值

                           */

                          ->protected void applyPropertyValues(String beanName, BeanDefinition mbd,BeanWrapper bw, PropertyValues pvs)

                         

                          /**

                           * 使用合适的实例化策略来构建指定的 bean(工厂方法 | 构造函数 | 自动装配

                           * @see #instantiateUsingFactoryMethod

                           * @see #autowireConstructor

                           * @see #instantiateBean

                           */

                          ->protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinitionmbd, Object[] args);

                         

                          // 使用 BeanWrapper 实例化 bean 定义的属性值

                          ->protected void populateBean(String beanName, RootBeanDefinition mbd,BeanWrapper bw)

                                   |

                                   |--->PropertyValues pvs = mbd.getPropertyValues(); 拿到 bean 中所有 <property name="id" value="1"/> Key Value

                                  

                                           

                         

                         

                 ->  实现ConfigurableListableBeanFactory 接口

                 ->  实现 BeanDefinitionRegistry 接口

 

 

 

 

         1、在spring同一个配置文件中,不能存在id相同的两个bean,否则会报错。

         2、在两个不同的spring配置文件中,可以存在id相同的两个bean,启动时,不会报错。这是因为spring ioc容器在加载bean的过程中,

         DefaultListableBeanFactory 会对id相同的bean进行处理:后加载的配置文件的bean,覆盖先加载的配置文件的bean

         DefaultListableBeanFactory类中,有个属性allowBeanDefinitionOverriding,默认值为true,该值就是用来指定出现两个beanid相同的情况下,如何进行处理。如果该值为false,则不会进行覆盖,而是抛出异常。

        

         =>DefaultListableBeanFactory

                 // 获取 Bean 类型的名称比如是否为 FactoryBean

                 ->private String[] doGetBeanNamesForType(ResolvableType type, booleanincludeNonSingletons, boolean allowEagerInit);

        

                

        

         AliasRegistry :定义对 alias 的简单增删改操作

                 ->SimpleAliasRegistry`AliasRegistry`接口的实现,使用Map缓存alias

                          //@param name 用户指定的名称

                          //@return          被转换的名字

                          ->public String canonicalName(String name) 别名解析 : 根据原始名称,将别名解析为规范名称。

                

         SingletonBeanRegistry:单例Bean容器(注册/获取)

                 -> DefaultSingletonBeanRegistry`SingletonBeanRegistry`的默认实现

                          /**根据 beanName 返回指定 bean 的单例对象,如果不存在返回 null

                           */

                          ->protected Object getSingleton(String beanName, boolean allowEarlyReference)

                  

        

         BeanFactoryBean的相关属性

                 ->HierarchicalBeanFactory:继承 BeanFactory ,在其基础之上增加了对 parentFactory 的支持

                

         BeanDefinition

                 ->BeanDefinitionRegistry定义对 BeanDefinition 的相关操作

 

         FactoryBeanRegistrySupportDefaultSinglentBeanRegistry基础上增加了 FactoryBean 的特殊处理

        

         ConfigurableBeanFactory提供配置 BeanFactory 的各种方法

        

         ListableBeanFactory:根据条件获取 Bean的配置清单

        

         AbstractBeanFactory:综合 FactoryBeanRegistrySupport ConfigurableListableBeanFactory 的功能

                 解析Bean以及将它存储在 mergedBeanDefinitions 中缓存起来

                 ->protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throwsBeansException

                

                 初始化自定义的PropertyEditorRegistry

                 ->protected void registerCustomEditors(PropertyEditorRegistry registry)

                

                 *将指定的 bean 添加到该工厂中的一次性bean的列表中,

                 *注册其DisposableBean接口和/或给定的销毁方法

                 *在工厂关机时被调用(如适用)。只适用于单例对象。

                 ->protected void registerDisposableBeanIfNecessary(String beanName, Object bean,RootBeanDefinition mbd)

                

                 ->protected RootBeanDefinition getMergedBeanDefinition(String beanName,BeanDefinition bd, BeanDefinition containingBd) throwsBeanDefinitionStoreException

                          ->  默认 RootBeanDefinition mbd = null;

                          ->      判断了Bean是否存在, 缓存(mergedBeanDefinitions)存在则从缓存中直接提取

                                   if(containingBd == null) {

                                            mbd= this.mergedBeanDefinitions.get(beanName);

                                   }

                          ->单例分配| | 由于 <bean id="person" class="com.battcn.bean.Person"/> 并未指定scope那么提取系统默认的RootBeanDefinition.SCOPE_SINGLETON

                                  

                                   if(!StringUtils.hasLength(mbd.getScope())) {

                                            mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);

                                   }

 

 

         ->SimpleInstantiationStrategy:在BeanFactory中使用的简单对象实例化策略。尽管它提供了子类的钩子以覆盖添加方法注入支持,例如通过覆盖方法。但是不支持方法注入

                 // 在此处通过 BeanUtils.instantiateClass(constructorToUse); 反射实例化出对象 

                 //     public Person() {

                 //                        System.out.println("init");

                 //               }

                 // 在调用完 BeanUtils.instantiateClass(constructorToUse); 就可以看到日志输出的 init

                 -> publicObject instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner);

Spring

-> lazy-init="default | true | false"

当我们使用lazy-init = "default"作为元素中的一个属性时,容器拾取由元素的default-lazy-init ="true | false"属性指定的值,并将其用作lazy-init ="true | false"

如果元素中不存在default-lazy-init 属性,则元素中的lazy-init =“default的行为就像lazy-init-“false一样。

        

结合 scope = "singleton"  可以理解为懒汉单例模式饿汉单例模式

Spring 的Bean默认单例

->  scope="singleton |prototype"默认 singleton = 单例  prototype = 多实例

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值