spring 知识点总结

  我不建议过多的看这些框架的代码,由于这些代码要完成任务须要不少琐碎的类实现,好比读取某个包下面的全部类,解析class的头文件,反射各类信息,再加上封装,颇有可能在读源码的过程当中掉到各类细节里出不来,因此读这种源码要事无巨细,理解原理便可。基本原理其实就是经过反射解析类及其类的各类信息,包括构造器、方法及其参数,属性。而后将其封装成bean定义信息类、constructor信息类、method信息类、property信息类,最终放在一个map里,也就是所谓的container,池等等,其实就是个map。html

         BeanFactory和BeanDefinition,一个是IOC的核心工厂接口,一个是IOC的bean定义接口,上章提到说咱们没法让BeanFactory持有一个Map<String,Object>来完成bean工厂的功能,是由于spring的初始化是能够控制的,能够到用的时候才将bean实例化供开发者使用,除非咱们将bean的lazy-init属性设置为true,初始化bean工厂时采用延迟加载。spring

          那么知道了上述两个接口,我相信很多人甚至不看源码都已经猜到spring是如何作的了。没错,就是让bean工厂持有一个Map<String,BeanDefinition>,这样就能够在任什么时候候咱们想用哪一个bean,取到它的bean定义,咱们就能够创造出一个新鲜的实例。sql

      当你写好配置文件,启动项目后,框架会先按照你的配置文件找到那个要scan的包,而后解析包里面的全部类,找到全部含有@bean,@service等注解的类,利用反射解析它们,包括解析构造器,方法,属性等等,而后封装成各类信息类放到一个map里。每当你须要一个bean的时候,框架就会从container找是否是有这个类的定义啊?若是找到则经过构造器new出来(这就是控制反转,不用你new,框架帮你new),再在这个类找是否是有要注入的属性或者方法,好比标有@autowired的属性,若是有则仍是到container找对应的解析类,new出对象,并经过以前解析出来的信息类找到setter方法,而后用该方法注入对象(这就是依赖注入)。若是其中有一个类container里没找到,则抛出异常,好比常见的spring没法找到该类定义,没法wire的异常。还有就是嵌套bean则用了一下递归,container会放到servletcontext里面,每次reQuest从servletcontext找这个container便可,不用屡次解析类定义。若是bean的scope是singleton,则会重用这个bean再也不从新建立,将这个bean放到一个map里,每次用都先从这个map里面找。若是scope是session,则该bean会放到session里面。仅此而已,不必花更多精力。建议仍是多看看底层的知识session

1afterPropertiesSet与init-method数据结构

(1)、init-method方法,初始化bean的时候执行,能够针对某个具体的bean进行配置。init-method须要在applicationContext.xml配置文档中bean的定义里头写明。例如:<bean id="TestBean" class="nju.software.xkxt.util.TestBean" init-method="init"></bean>
这样,当TestBean在初始化的时候会执行TestBean中定义的init方法。   
(2)、afterPropertiesSet方法,初始化bean的时候执行,能够针对某个具体的bean进行配置。afterPropertiesSet 必须实现 InitializingBean接口。实现 InitializingBean接口必须实现afterPropertiesSet方法。 InitializingBean是一个接口,它仅仅包含一个方法:afterPropertiesSet()。Spring要求init-method是一个无参数的方法,若是init-method指定的方法中有参数,那么Spring将会抛出异常init-method指定的方法能够是public、protected以及private的,而且方法也能够是final的。
(3)、BeanPostProcessor,针对全部Spring上下文中全部的bean,能够在配置文档applicationContext.xml中配置一个BeanPostProcessor,而后对全部的bean进行一个初始化方法以前和以后的代理。BeanPostProcessor接口中有两个方法: postProcessBeforeInitialization和postProcessAfterInitialization。前者postProcessBeforeInitialization在实例化及依赖注入完成后、在任何初始化代码(好比配置文件中的init-method)调用以前调用;后者postProcessAfterInitialization在初始化代码调用以后调用
 postProcessBeforeInitialization方法在bean初始化以前执行, postProcessAfterInitialization方法在bean初始化以后执行。
mybatis


2 proxy-target-class 做用 该属性值默认为false,表示使用JDK动态代理织入加强;当值为true时,表示使用CGLib动态代理织入加强;可是,即便设置为false,若是目标类没有生命接口,则spring将自动使用CGLib动态代理
当要使用实现了某个接口的类让spring来生成bean时,无需在aop配置中添加proxy-target-class,由于它默认为false.app

2 lazy-init详解做用 该属性值默认为false,表示ApplicationContext实现的默认行为就是在启动时将全部singleton bean提早进行实例化(也就是依赖注入),lazy-init 设置只对scop属性为singleton的bean起做用。框架

3 Spring bean做用域与生命周期ide

 参考文章:Spring BeanBean的做用域及生命周期函数

实例化。Spring经过new关键字将一个Bean进行实例化,JavaBean都有默认的构造函数,所以不须要提供构造参数。填入属性。Spring根据xml文件中的配置经过调用Bean中的setXXX方法填入对应的属性。事件通知。Spring依次检查Bean是否实现了BeanNameAware、BeanFactoryAware、ApplicationContextAware、BeanPostProcessor、InitializingBean接口,若是有的话,依次调用这些接口。使用。应用程序能够正常使用这个Bean了。销毁。若是Bean实现了DisposableBean接口,就调用其destroy方法。

注意:若是bean的scope设为prototype时,当ctx.close时,destroy方法不会被调用.

缘由:对于prototype做用域的bean,有一点很是重要,那就是Spring不能对一个prototype bean的整个生命周期负责:容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例漠不关心了。无论何种做用域,容器都会调用全部对象的初始化生命周期回调方法。但对prototype而言,任何配置好的析构生命周期回调方法都将不会 被调用。清除prototype做用域的对象并释听任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被prototype做用域bean占用资源的一种可行方式是,经过使用bean的后置处理器,该处理器持有要被清除的bean的引用。)谈及prototype做用域的bean时,在某些方面你能够将Spring容器的角色看做是Java new 操做的替代者。任何迟于该时间点的生命周期事宜都得交由客户端来处理。
4 BeanDefinition的载入和解析

对IoC容器来讲,这个载入过程,至关于把定义的BeanDefinition在IoC容器中转化成一个Spring内部表示的数据结构的过程。IoC容器对Bean的管理和依赖注入功能的实现,是经过对其持有的BeanDefinition进行各类相关操做来完成的。这些BeanDefinition数据在IoC容器中经过一个HashMap来保持和维护。固然这只是一种比较简单的维护方式,若是须要提升IoC容器的性能和容量,彻底能够本身作一些扩展。

IoC容器的初始化入口,也就是看一下refresh方法。这个方法的最初是在FileSystemXmlApplicationContext的构造函数中被调用的,它的调用标志着容器初始化的开始,
这些初始化对象就是Bean. 

 

4 Spring容器初始化过程

spring的IoC容器初始化包括:Bean定义资源文件的定位、载入和注册3个基本过程。当 BeanDefinition 注册完毕之后, Spring Bean 工厂就能够随时根据须要进行实例化了。对于 XmlBeanFactory 来讲,实例化默认是延迟进行的,也就是说在 getBean 的时候才会;而对于 ApplicationContext 来讲,实例化会在容器启动后经过AbstractApplicationContext 中 reflash 方法自动进行,主要通过方法链: reflesh()   à finishBeanFactoryInitialization (factory) à DefaultListableBeanFactory.preInstantiateSingletons (), 在这里会根据注册的 BeanDefinition 信息依此调用 getBean(beanName) 。而真正实例化的逻辑和 BeanFactory 是“异曲同工”的,全部有关 Bean 实例化均可以从 getBean(beanName) 入手。IoC容器和上下文初始化通常不包含Bean依赖注入的实现。通常而言,依赖注入发送在应用第一次经过getBean方法向容器获取Bean时。可是有个特例是:IoC容器预实例化配置的lazyinit属性,若是某个Bean设置了lazyinit属性,则该Bean的依赖注入在IoC容器初始化时就预先完成了

5 如何启动spring容器:在Web项目中,启动Spring容器的方式有三种,ContextLoaderListener、ContextLoadServlet、ContextLoaderPlugin。

5 ApplicationContext和beanfactory区别:BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory没法支持spring的许多插件,如AOP功能、Web应用等。 ApplicationContext接口,它由BeanFactory接口派生而来,于是提供BeanFactory全部的功能

参考文章:Spring中ApplicationContext和beanfactory区别 .

 6 spring如何跟struts2: struts2-spring-plugin.jar这个插件重写了struts的对象工厂,当建立一个action类时,它会根据struts的配置文件的class属性的值与spring配置文件中的id属性的值相匹配

参考文章:spring与struts2结合

 7 spring如何跟mybatis:Mybatis-Spring给咱们封装了一个SqlSessionFactoryBean,这个对象包含了3个必备属性,分别是数据源、扫描xml和扫描dao层用的

 

[html]  view plain  copy
 
  1. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  2.               <property name="dataSource" ref="dataSource" />  
  3.               <property name="mapperLocations"  
  4.                      value="classpath:com/tiantian/ckeditor/mybatis/mappers/*Mapper.xml" />  
  5.               <property name="typeAliasesPackage" value="com.tiantian.ckeditor.model" />  
  6. </bean>  

 

mapperLocations:它表示咱们的Mapper文件存放的位置,当咱们的Mapper文件跟对应的Mapper接口处于同一位置的时候能够不用指定该属性的值。

configLocation:用于指定Mybatis的配置文件位置。若是指定了该属性,那么会以该配置文件的内容做为配置信息构建对应的SqlSessionFactoryBuilder,可是后续属性指定的内容会覆盖该配置文件里面指定的对应内容。

 typeAliasesPackage:它通常对应咱们的实体类所在的包,这个时候会自动取对应包中不包括包名的简单类名做为包括包名的别名。多个package之间能够用逗号或者分号等来进行分隔。

我不建议过多的看这些框架的代码,由于这些代码要完成任务须要不少琐碎的类实现,好比读取某个包下面的全部类,解析class的头文件,反射各类信息,再加上封装,颇有可能在读源码的过程当中掉到各类细节里出不来,因此读这种源码要事无巨细,理解原理便可。基本原理其实就是经过反射解析类及其类的各类信息,包括构造器、方法及其参数,属性。而后将其封装成bean定义信息类、constructor信息类、method信息类、property信息类,最终放在一个map里,也就是所谓的container,池等等,其实就是个map。

         BeanFactory和BeanDefinition,一个是IOC的核心工厂接口,一个是IOC的bean定义接口,上章提到说咱们没法让BeanFactory持有一个Map<String,Object>来完成bean工厂的功能,是由于spring的初始化是能够控制的,能够到用的时候才将bean实例化供开发者使用,除非咱们将bean的lazy-init属性设置为true,初始化bean工厂时采用延迟加载。

          那么知道了上述两个接口,我相信很多人甚至不看源码都已经猜到spring是如何作的了。没错,就是让bean工厂持有一个Map<String,BeanDefinition>,这样就能够在任什么时候候咱们想用哪一个bean,取到它的bean定义,咱们就能够创造出一个新鲜的实例。

      当你写好配置文件,启动项目后,框架会先按照你的配置文件找到那个要scan的包,而后解析包里面的全部类,找到全部含有@bean,@service等注解的类,利用反射解析它们,包括解析构造器,方法,属性等等,而后封装成各类信息类放到一个map里。每当你须要一个bean的时候,框架就会从container找是否是有这个类的定义啊?若是找到则经过构造器new出来(这就是控制反转,不用你new,框架帮你new),再在这个类找是否是有要注入的属性或者方法,好比标有@autowired的属性,若是有则仍是到container找对应的解析类,new出对象,并经过以前解析出来的信息类找到setter方法,而后用该方法注入对象(这就是依赖注入)。若是其中有一个类container里没找到,则抛出异常,好比常见的spring没法找到该类定义,没法wire的异常。还有就是嵌套bean则用了一下递归,container会放到servletcontext里面,每次reQuest从servletcontext找这个container便可,不用屡次解析类定义。若是bean的scope是singleton,则会重用这个bean再也不从新建立,将这个bean放到一个map里,每次用都先从这个map里面找。若是scope是session,则该bean会放到session里面。仅此而已,不必花更多精力。建议仍是多看看底层的知识

1afterPropertiesSet与init-method

(1)、init-method方法,初始化bean的时候执行,能够针对某个具体的bean进行配置。init-method须要在applicationContext.xml配置文档中bean的定义里头写明。例如:<bean id="TestBean" class="nju.software.xkxt.util.TestBean" init-method="init"></bean>
这样,当TestBean在初始化的时候会执行TestBean中定义的init方法。   
(2)、afterPropertiesSet方法,初始化bean的时候执行,能够针对某个具体的bean进行配置。afterPropertiesSet 必须实现 InitializingBean接口。实现 InitializingBean接口必须实现afterPropertiesSet方法。 InitializingBean是一个接口,它仅仅包含一个方法:afterPropertiesSet()。Spring要求init-method是一个无参数的方法,若是init-method指定的方法中有参数,那么Spring将会抛出异常init-method指定的方法能够是public、protected以及private的,而且方法也能够是final的。
(3)、BeanPostProcessor,针对全部Spring上下文中全部的bean,能够在配置文档applicationContext.xml中配置一个BeanPostProcessor,而后对全部的bean进行一个初始化方法以前和以后的代理。BeanPostProcessor接口中有两个方法: postProcessBeforeInitialization和postProcessAfterInitialization。前者postProcessBeforeInitialization在实例化及依赖注入完成后、在任何初始化代码(好比配置文件中的init-method)调用以前调用;后者postProcessAfterInitialization在初始化代码调用以后调用
 postProcessBeforeInitialization方法在bean初始化以前执行, postProcessAfterInitialization方法在bean初始化以后执行。


2 proxy-target-class 做用 该属性值默认为false,表示使用JDK动态代理织入加强;当值为true时,表示使用CGLib动态代理织入加强;可是,即便设置为false,若是目标类没有生命接口,则spring将自动使用CGLib动态代理
当要使用实现了某个接口的类让spring来生成bean时,无需在aop配置中添加proxy-target-class,由于它默认为false.

2 lazy-init详解做用 该属性值默认为false,表示ApplicationContext实现的默认行为就是在启动时将全部singleton bean提早进行实例化(也就是依赖注入),lazy-init 设置只对scop属性为singleton的bean起做用。

3 Spring bean做用域与生命周期

 参考文章:Spring BeanBean的做用域及生命周期

实例化。Spring经过new关键字将一个Bean进行实例化,JavaBean都有默认的构造函数,所以不须要提供构造参数。填入属性。Spring根据xml文件中的配置经过调用Bean中的setXXX方法填入对应的属性。事件通知。Spring依次检查Bean是否实现了BeanNameAware、BeanFactoryAware、ApplicationContextAware、BeanPostProcessor、InitializingBean接口,若是有的话,依次调用这些接口。使用。应用程序能够正常使用这个Bean了。销毁。若是Bean实现了DisposableBean接口,就调用其destroy方法。

注意:若是bean的scope设为prototype时,当ctx.close时,destroy方法不会被调用.

缘由:对于prototype做用域的bean,有一点很是重要,那就是Spring不能对一个prototype bean的整个生命周期负责:容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例漠不关心了。无论何种做用域,容器都会调用全部对象的初始化生命周期回调方法。但对prototype而言,任何配置好的析构生命周期回调方法都将不会 被调用。清除prototype做用域的对象并释听任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被prototype做用域bean占用资源的一种可行方式是,经过使用bean的后置处理器,该处理器持有要被清除的bean的引用。)谈及prototype做用域的bean时,在某些方面你能够将Spring容器的角色看做是Java new 操做的替代者。任何迟于该时间点的生命周期事宜都得交由客户端来处理。
4 BeanDefinition的载入和解析

对IoC容器来讲,这个载入过程,至关于把定义的BeanDefinition在IoC容器中转化成一个Spring内部表示的数据结构的过程。IoC容器对Bean的管理和依赖注入功能的实现,是经过对其持有的BeanDefinition进行各类相关操做来完成的。这些BeanDefinition数据在IoC容器中经过一个HashMap来保持和维护。固然这只是一种比较简单的维护方式,若是须要提升IoC容器的性能和容量,彻底能够本身作一些扩展。

IoC容器的初始化入口,也就是看一下refresh方法。这个方法的最初是在FileSystemXmlApplicationContext的构造函数中被调用的,它的调用标志着容器初始化的开始,
这些初始化对象就是Bean. 

 

4 Spring容器初始化过程

spring的IoC容器初始化包括:Bean定义资源文件的定位、载入和注册3个基本过程。当 BeanDefinition 注册完毕之后, Spring Bean 工厂就能够随时根据须要进行实例化了。对于 XmlBeanFactory 来讲,实例化默认是延迟进行的,也就是说在 getBean 的时候才会;而对于 ApplicationContext 来讲,实例化会在容器启动后经过AbstractApplicationContext 中 reflash 方法自动进行,主要通过方法链: reflesh()   à finishBeanFactoryInitialization (factory) à DefaultListableBeanFactory.preInstantiateSingletons (), 在这里会根据注册的 BeanDefinition 信息依此调用 getBean(beanName) 。而真正实例化的逻辑和 BeanFactory 是“异曲同工”的,全部有关 Bean 实例化均可以从 getBean(beanName) 入手。IoC容器和上下文初始化通常不包含Bean依赖注入的实现。通常而言,依赖注入发送在应用第一次经过getBean方法向容器获取Bean时。可是有个特例是:IoC容器预实例化配置的lazyinit属性,若是某个Bean设置了lazyinit属性,则该Bean的依赖注入在IoC容器初始化时就预先完成了

5 如何启动spring容器:在Web项目中,启动Spring容器的方式有三种,ContextLoaderListener、ContextLoadServlet、ContextLoaderPlugin。

5 ApplicationContext和beanfactory区别:BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory没法支持spring的许多插件,如AOP功能、Web应用等。 ApplicationContext接口,它由BeanFactory接口派生而来,于是提供BeanFactory全部的功能

参考文章:Spring中ApplicationContext和beanfactory区别 .

 6 spring如何跟struts2: struts2-spring-plugin.jar这个插件重写了struts的对象工厂,当建立一个action类时,它会根据struts的配置文件的class属性的值与spring配置文件中的id属性的值相匹配

参考文章:spring与struts2结合

 7 spring如何跟mybatis:Mybatis-Spring给咱们封装了一个SqlSessionFactoryBean,这个对象包含了3个必备属性,分别是数据源、扫描xml和扫描dao层用的

 

[html]  view plain  copy
 
  1. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  2.               <property name="dataSource" ref="dataSource" />  
  3.               <property name="mapperLocations"  
  4.                      value="classpath:com/tiantian/ckeditor/mybatis/mappers/*Mapper.xml" />  
  5.               <property name="typeAliasesPackage" value="com.tiantian.ckeditor.model" />  
  6. </bean>  

 

mapperLocations:它表示咱们的Mapper文件存放的位置,当咱们的Mapper文件跟对应的Mapper接口处于同一位置的时候能够不用指定该属性的值。

configLocation:用于指定Mybatis的配置文件位置。若是指定了该属性,那么会以该配置文件的内容做为配置信息构建对应的SqlSessionFactoryBuilder,可是后续属性指定的内容会覆盖该配置文件里面指定的对应内容。

 typeAliasesPackage:它通常对应咱们的实体类所在的包,这个时候会自动取对应包中不包括包名的简单类名做为包括包名的别名。多个package之间能够用逗号或者分号等来进行分隔。

相关文章
相关标签/搜索