Spring


第一部分 Spring IOC

一、概念

  1. Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
  2. Spring 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化 Bean 并建立 Bean 之间的依赖关系。 Spring 的 IoC 容器在完成这些底层工作的基础上,还提供了 Bean 实例缓存、生命周期管理、 Bean 实例代理、事件发布、资源装载等高级服务。
  3. 依赖注入(Dependency Injection):组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。IOC使用依赖注入实现。

二、实现方式

  1. 配置XML文件
  2. 依赖注入
    • 构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
    • Setter方法注入:容器通过调用无参构造器或无参static工厂 方法实例化bean后,调用该bean的setter方法,实现了基于setter的依赖注入。
    • 接口注入:基于接口将调用与实现分离。这种依赖注入的方式必须实现容器所规定的接口,使程序代码和容器的API绑定在一起,这不是理想的依赖注入方式,所以Spring也不支持这种方式;
  3. 自动装配:
  4. 使用注解形式实现IoC:

三、实现原理——工厂模式加反射机制

  1. BeanFactory

    BeanFactory体系架构

    • BeanDefinitionRegistry: Spring 配置文件中每一个节点元素在 Spring 容器里都通过一个 BeanDefinition 对象表示,它描述了 Bean 的配置信息。而 BeanDefinitionRegistry 接口提供了向容器手工注册 BeanDefinition 对象的方法。
    • BeanFactory 接口位于类结构树的顶端 ,它最主要的方法就是 getBean(String beanName),该方法从容器中返回特定名称的 Bean,BeanFactory 的功能通过其他的接口得到不断扩展:
    • ListableBeanFactory:该接口定义了访问容器中 Bean 基本信息的若干方法,如查看Bean 的个数、获取某一类型 Bean 的配置名、查看容器中是否包括某一 Bean 等方法;
    • HierarchicalBeanFactory:父子级联 IoC 容器的接口,子容器可以通过接口方法访问父容器; 通过 HierarchicalBeanFactory 接口, Spring 的 IoC 容器可以建立父子层级关联的容器体系,子容器可以访问父容器中的 Bean,但父容器不能访问子容器的 Bean。Spring 使用父子容器实现了很多功能,比如在 Spring MVC 中,展现层 Bean 位于一个子容器中,而业务层和持久层的 Bean 位于父容器中。这样,展现层 Bean 就可以引用业务层和持久层的 Bean,而业务层和持久层的 Bean 则看不到展现层的 Bean。
    • ConfigurableBeanFactory:是一个重要的接口,增强了 IoC 容器的可定制性,它定义了设置类装载器、属性编辑器、容器初始化后置处理器等方法;
    • AutowireCapableBeanFactory:定义了将容器中的 Bean 按某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法;
    • SingletonBeanRegistry:定义了允许在运行期间向容器注册单实例 Bean 的方法;
  2. ApplicationContext:ApplicationContext 继承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基础上,还通过多个其他的接口扩展了 BeanFactory 的功能

    ApplicationContext

    • ClassPathXmlApplicationContext:默认从类路径加载配置文件
    • FileSystemXmlApplicationContext:默认从文件系统中装载配置文件
    • ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件等。实现了 ApplicationListener 事件监听接口的 Bean 可以接收到容器事件 , 并对事件进行响应处理 。 在 ApplicationContext 抽象实现类AbstractApplicationContext 中,我们可以发现存在一个 ApplicationEventMulticaster,它负责保存所有监听器,以便在容器产生上下文事件时通知这些事件监听者。
    • MessageSource:为应用提供 i18n 国际化消息访问的功能;
    • ResourcePatternResolver : 所 有 ApplicationContext 实现类都实现了类似于PathMatchingResourcePatternResolver 的功能,可以通过带前缀的 Ant 风格的资源文件路径装载 Spring 的配置文件。
    • LifeCycle:该接口是 Spring 2.0 加入的,该接口提供了 start()和 stop()两个方法,主要用于控制异步处理过程。在具体使用时,该接口同时被 ApplicationContext 实现及具体 Bean 实现, ApplicationContext 会将 start/stop 的信息传递给容器中所有实现了该接口的 Bean,以达到管理和控制 JMX、任务调度等目的。
    • ConfigurableApplicationContext 扩展于 ApplicationContext,它新增加了两个主要的方法: refresh()和 close(),让 ApplicationContext 具有启动、刷新和关闭应用上下文的能力。在应用上下文关闭的情况下调用 refresh()即可启动应用上下文,在已经启动的状态下,调用 refresh()则清除缓存并重新装载配置信息,而调用close()则可关闭应用上下文。这些接口方法为容器的控制管理带来了便利,但作为开发者,我们并不需要过多关心这些方法。
  3. WebApplicationContext:WebApplicationContext 是专门为 Web 应用准备的,它允许从相对于 Web 根目录的路径中装载配置文件完成初始化工作。

    WebApplicationContext

  4. 工作机制

    • 1、ResourceLoader从存储介质中加载Spring配置信息,并使用Resource表示这个配置文件的资源;

    • 2、BeanDefinitionReader读取Resource所指向的配置文件资源,然后解析配置文件。配置文件中每一个解析成一个BeanDefinition对象,并保存到BeanDefinitionRegistry中;

    • 3、容器扫描BeanDefinitionRegistry中的BeanDefinition,使用Java的反射机制自动识别出Bean工厂后处理后器(实现BeanFactoryPostProcessor接口)的Bean,然后调用这些Bean工厂后处理器对BeanDefinitionRegistry中的BeanDefinition进行加工处理。主要完成以下两项工作:

      • 1)对使用到占位符的元素标签进行解析,得到最终的配置值,这意味对一些半成品式的BeanDefinition对象进行加工处理并得到成品的BeanDefinition对象;
      • 2)对BeanDefinitionRegistry中的BeanDefinition进行扫描,通过Java反射机制找出所有属性编辑器的Bean(实现java.beans.PropertyEditor接口的Bean),并自动将它们注册到Spring容器的属性编辑器注册表中(PropertyEditorRegistry);
    • 4.Spring容器从BeanDefinitionRegistry中取出加工后的BeanDefinition,并调用InstantiationStrategy着手进行Bean实例化的工作;

    • 5.在实例化Bean时,Spring容器使用BeanWrapper对Bean进行封装,BeanWrapper提供了很多以Java反射机制操作Bean的方法,它将结合该Bean的BeanDefinition以及容器中属性编辑器,完成Bean属性的设置工作;

    • 6.利用容器中注册的Bean后处理器(实现BeanPostProcessor接口的Bean)对已经完成属性设置工作的Bean进行后续加工,直接装配出一个准备就绪的Bean。

Spring容器从加载配置文件到创建出一个完整Bea

四、循环依赖

  1. 概念:ABean创建–>依赖了B属性–>触发BBean创建—>B依赖了A属性—>需要ABean(但ABean还在创建过程中)

  2. 三级缓存

    • 一级缓存为singletonObjects:singletonObjects中缓存的是已经经历了完整生命周期的bean对象。
    • 二级缓存为earlySingletonObjects:earlySingletonObjects比singletonObjects多了一个early,表示缓存的是早期的bean对象。早期是什么意思?表示Bean的生命周期还没走完就把这个Bean放入了earlySingletonObjects。缓存提前拿原始对象进行了AOP之后得到的代理对象,原始对象还没有进行属性注入和后续的BeanPostProcessor等生命周期
    • 三级缓存为singletonFactories:singletonFactories中缓存的是ObjectFactory,表示对象工厂,用来创建某个对象的。缓存的是一个ObjectFactory,主要用来去生成原始对象进行了AOP之后得到的代理对象
    • 解决循环依赖:A的Bean在创建过程中,在进行依赖注入之前,先把A的原始Bean放入缓存(提早暴露,只要放到缓存了,其他Bean需要时就可以从缓存中拿了),放入缓存后,再进行依赖注入,此时A的Bean依赖了B的Bean,如果B的Bean不存在,则需要创建B的Bean,而创建B的Bean的过程和A一样,也是先创建一个B的原始对象,然后把B的原始对象提早暴露出来放入缓存中,然后在对B的原始对象进行依赖注入A,此时能从缓存中拿到A的原始对象(虽然是A的原始对象,还不是最终的Bean),B的原始对象依赖注入完了之后,B的生命周期结束,那么A的生命周期也能结束。

    三级缓存解决循环依赖

    • 问题:如果A的原始对象注入给B的属性之后,A的原始对象进行了AOP产生了一个代理对象,此时就会出现,对于A而言,它的Bean对象其实应该是AOP之后的代理对象,而B的a属性对应的并不是AOP之后的代理对象,这就产生了冲突。B依赖的A和最终的A不是同一个对象
    • 三级缓存解决:从earlySingletonObjects放入singletonObjects,保持一个代理对象。

    三级缓存解决循环依赖2

参考链接

第二部分 Spring beans

一、概念

  1. Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中 的形式定义。

二、Spring Bean 作用域

  1. singleton : 单例模式,Spring IoC 容器中只会存在一个共享的 Bean 实例,无论有多少个Bean 引用它,始终指向同一对象。该模式在多线程下是不安全的。
  2. prototype:原型模式,每次通过 Spring 容器获取 prototype 定义的 bean 时,容器都将创建一个新的 Bean 实例,每个 Bean 实例都有自己的属性和状态。
  3. request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
  4. session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
  5. global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

三、Spring Bean 生命周期(实例化 -> 属性赋值 -> 初始化 -> 销毁)

  1. 实例化:实例化一个 Bean,也就是我们常说的 new。
  2. IOC 依赖注入:按照 Spring 上下文对实例化的 Bean 进行配置,也就是 IOC 注入。
  3. setBeanName 实现:如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String)方法,此处传递的就是 Spring 配置文件中 Bean 的 id 值
  4. BeanFactoryAware 实现:如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory,setBeanFactory(BeanFactory)传递的是 Spring 工厂自身(可以用这个方式来获取其它 Bean,只需在 Spring 配置文件中配置一个普通的 Bean 就可以)。
  5. ApplicationContextAware 实现:如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用setApplicationContext(ApplicationContext)方法,传入 Spring 上下文(同样这个方式也可以实现步骤 4 的内容,但比 4 更好,因为 ApplicationContext 是 BeanFactory 的子接口,有更多的实现方法)
  6. postProcessBeforeInitialization 接口实现 - 初始化预处理:如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor 经常被用作是 Bean 内容的更改,并且由于这个是在 Bean 初始化结束时调用那个的方法,也可以被应用于内存或缓存技术。
  7. init-method:如果 Bean 在 Spring 配置文件中配置了 init-method 属性会自动调用其配置的初始化方法。
  8. postProcessAfterInitialization:如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用postProcessAfterInitialization(Object obj, String s)方法。
    注:以上工作完成以后就可以应用这个 Bean 了,那这个 Bean 是一个 Singleton 的,所以一般情况下我们调用同一个 id 的 Bean 会是在内容地址相同的实例,当然在 Spring 配置文件中也可以配置非 Singleton。
  9. Destroy 过期自动 清理阶段:当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调用那个其实现的 destroy()方法;
  10. destroy-method 自配置清理:最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其配置的销毁方法。

Spring beans生命周期

四、bean装配

  1. 装配:装配,或bean 装配是指在Spring 容器中把bean组装到一起,前提是容器需要知道bean的依赖关系,如何通过依赖注入来把它们装配到一起。
  2. 自动装配:在Spring框架中,在配置文件中设定bean的依赖关系是一个很好的机制,Spring 容器能够自动装配相互合作的bean,这意味着容器不需要和配置,能通过Bean工厂自动处理bean之间的协作。这意味着 Spring可以通过向Bean Factory中注入的方式自动搞定bean之间的依赖关系。自动装配可以设置在每个bean上,也可以设定在特定的bean上。
  3. 在spring中,对象无需自己查找或创建与其关联的其他对象,由容器负责把需要相互协作的对象引用赋予各个对象,使用autowire来配置自动装载模式。
    • no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。
    • byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。
    • byType:通过参数的数据类型进行自动装配。
    • constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。
    • autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。
  4. 自动装配的局限性是:
    • 重写:你仍需用 和 配置来定义依赖,意味着总要重写自动装配。
    • 基本数据类型:你不能自动装配简单的属性,如基本数据类型,String字符串,和类。
    • 模糊特性:自动装配不如显式装配精确,如果有可能,建议使用显式装配。

参考连接:

第三部分 Spring AOP

一、概念

  1. 面对切面编程,这是一种编程模式,他允许程序员通过自定义的横切点进行模块化,将那些影响多个类的行为封装到课重用的模块中。

  2. AOP 要达到的效果是,保证开发者不修改源代码的前提下,去为系统中的业务组件添加某种通用功能。AOP 的本质是由 AOP 框架修改业务组件的多个方法的源代码,AOP 其实就是代理模式的典型应用。

  3. 术语

    • 通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理。

      Advice

    • 连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出。在 Spring AOP 中,连接点总是方法的调用。

    • 切点(PointCut): 可以插入增强处理的连接点。

    • 切面(Aspect): 切面是通知和切点的结合。

    • 引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。

    • 织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,这个过程就是织入。

  4. 实现方法:

    • 静态 AOP 实现, AOP 框架在编译阶段对程序源代码进行修改,生成了静态的 AOP 代理类(生成的 *.class 文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。
    • 动态 AOP 实现, AOP 框架在运行阶段对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP。

二、使用方法

  1. 通过注解配置 Spring AOP
  2. 通过 XML 配置文件声明切面

三、实现原理

  1. 利用代理模式动态的实现AOP,从具体的技术细节又可以分为静态代理,动态代理,CGLIB生成子类代理。
  2. 使用预编译的方法静态进行代理。
  3. 使用自定义加载器的方法动态进行代理。

参考链接:

第四部分 Spring MVC

Spring MVC和spring的关系 SpringMVC体系结构

一、请求处理流程

  1. 首先用户发送请求到前端控制器(DispatcherServlet),前端控制器根据请求信息(比如URL)决定将请求分发给哪个页面控制器(Controller)来处理。对应上图中的步骤1、2。
  2. 页面控制器接收到请求之后,进行业务处理,处理完毕之后返回一个ModelAndView。对应上图中的步骤3、4、5。
  3. 前端控制器将控制权收回,然后根据返回的逻辑视图名,通过视图解析器选择真正的视图,将模型数据传入供其渲染展示。对应上图中的步骤6、7。
  4. 前端控制器再次收回控制权,将响应结果返回给浏览器客户端,至此整个流程结束。对应上图中的步骤8。

SpringMVC请求处理流程

二、常用注解

MVC 常用注解

参考链接

第五部分 Spring Boot

一、概念

  1. spring boot就是一个大框架里面包含了许许多多的东西,其中spring就是最核心的内容之一,当然就包含spring mvc。spring mvc 是只是spring 处理web层请求的一个模块。因此他们的关系大概就是这样:spring mvc < spring <springboot。

参考链接

第六部分 Spring事件

一、概念

二、事件类型

  1. 上下文更新事件(ContextRefreshedEvent):在调用 ConfigurableApplicationContext 接口中的refresh()方法时被触发。
  2. 上下文开始事件(ContextStartedEvent):当容器调用 ConfigurableApplicationContext的Start()方法开始/重新开始容器时触 发该事件。
  3. 上下文停止事件(ContextStoppedEvent):当容器调用 ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
  4. 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
  5. 请求处理事件(RequestHandledEvent):在Web应用中,当一个 http请求(request)结束触发该事件。如果一个bean实现了 ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean 会自动被通知。

第七部分 Spring注解

一、注解类型

  1. Controller:标识一个该类是Spring MVC controller处理器,用来创建处理http请求的对象.
  2. RestController:spring4之后加入的注解,原来在@Controller中返回json需要@ResponseBody来配合,如果直接用@RestController替代@Controller就不需要再配置@ResponseBody,默认返回json格式。
  3. Service:用于标注业务层组件,以注解的方式把这个类注入到spring配置中
  4. Autowired:用来装配bean,都可以写在字段上,或者方法上。默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,例如:@Autowired(required=false)
  5. RequestMapping:类定义处: 提供初步的请求映射信息,相对于 WEB 应用的根目录。方法处: 提供进一步的细分映射信息,相对于类定义处的 URL。(还有许多属性参数,不细讲,可自行查找)
  6. RequestParam:用于将请求参数区数据映射到功能处理方法的参数上,其中course_id就是接口传递的参数,id就是映射course_id的参数名,也可以不写value属性
  7. NonNull:标注在方法、字段、参数上,表示对应的值可以为空。
  8. Nullable:标注在方法、字段、参数上,表示对应的值不能为空。
  9. Resource(等同于@Autowired):@Autowired按byType自动注入,而@Resource默认按 byName自动注入,@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
  10. Qualifier:当一个接口有多个实现类时,就可以用此注解表明哪个实现类才是我们所需要的,名称为我们之前定义@Service注解的名称之一。
  11. Component:把普通pojo实例化到spring容器中,相当于配置文件中的它泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候),我们就可以使用@Component来标注这个类。此外,被@controller 、@service、@repository 、@component 注解的类,都会把这些类纳入进spring容器中进行管理
  12. Repository:作用为给bean在容器中命名定义一个接口
  13. Scope:@Scope注解是springIoc容器中的一个作用域,在 Spring IoC 容器中具有以下几种作用域:基本作用域singleton(单例)、prototype(多例),Web 作用域(reqeust、session、globalsession),自定义作用域。(@Scope注解默认的singleton单例模式)
  14. Bean:产生一个bean的方法,并且交给Spring容器管理,相当于配置文件中的
  15. Transactional
  16. Aspect:作用是标记一个切面类(spring不会将切面注册为Bean也不会增强,但是需要扫描)
  17. Pointcut:定义切点,切点表达式(execution(权限访问符 返回值类型 方法所属的类名包路径.方法名(形参类型) 异常类型))
  18. Before:前置增强,配合@Pointcut一起使用
  19. AfterReturning:后置增强,配合@Pointcut一起使用
  20. Around:环绕增强,配合@Pointcut一起使用
  21. AfterThrowing:异常抛出增强,配合@Pointcut一起使用
  22. After:最终增强(最后执行),配合@Pointcut一起使用
  23. Cacheable(结合Redis搭建缓存机制):用来标记缓存查询。可用用于方法或者类中
  24. CacheEvict:用来标记要清空缓存的方法,当这个方法被调用后,即会清空缓存。@CacheEvict(value=”UserCache”)
  25. Required(注释检查):适用于bean属性setter方法,并表示受影响的bean属性必须在XML配置文件在配置时进行填充。否则,容器会抛出一个BeanInitializationException异常。
  26. ModelAttribute

参考链接

第八部分 Spring事务

一、概念

  1. Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

二、Spring事务的配置方式

  1. 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
  2. 声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。

三、事务的传播机制

  1. 概念:事务的传播性一般用在事务嵌套的场景,比如一个事务方法里面调用了另外一个事务方法,那么两个方法是各自作为独立的方法提交还是内层的事务合并到外层的事务一起提交,这就是需要事务传播机制的配置来确定怎么样执行。
  2. 类型:
    • PROPAGATION_REQUIRED:Spring默认的传播机制,能满足绝大部分业务需求,如果外层有事务,则当前事务加入到外层事务,一块提交,一块回滚。如果外层没有事务,新建一个事务执行
    • PROPAGATION_REQUES_NEW:该事务传播机制是每次都会新开启一个事务,同时把外层事务挂起,当当前事务执行完毕,恢复上层事务的执行。如果外层没有事务,执行当前新开启的事务即可
    • PROPAGATION_SUPPORT:如果外层有事务,则加入外层事务,如果外层没有事务,则直接使用非事务方式执行。完全依赖外层的事务
    • PROPAGATION_NOT_SUPPORT:该传播机制不支持事务,如果外层存在事务则挂起,执行完当前代码,则恢复外层事务,无论是否异常都不会回滚当前的代码
    • PROPAGATION_NEVER:该传播机制不支持外层事务,即如果外层有事务就抛出异常
    • PROPAGATION_MANDATORY:与NEVER相反,如果外层没有事务,则抛出异常
    • PROPAGATION_NESTED:该传播机制的特点是可以保存状态保存点,当前事务回滚到某一个点,从而避免所有的嵌套事务都回滚,即各自回滚各自的,如果子事务没有把异常吃掉,基本还是会引起全部回滚的。

四、事务实现原理

  1. Spring事务底层是基于数据库事务和AOP机制的
  2. 首先对于使用了@Transactional注解的Bean,Spring会创建一个代理对象作为Bean
  3. 当调用代理对象的方法时,会先判断该方法上是否加了@Transactional注解
  4. 如果加了,那么则利用事务管理器创建一个数据库连接
  5. 并且修改数据库连接的autocommit属性为false,禁止此连接的自动提交,这是实现Spring事务非常重要的一步
  6. 然后执行当前方法,方法中会执行sql
  7. 执行完当前方法后,如果没有出现异常就直接提交事务
  8. 如果出现了异常,并且这个异常是需要回滚的就会回滚事务,否则仍然提交事务
  9. Spring事务的隔离级别对应的就是数据库的隔离级别
  10. Spring事务的传播机制是Spring事务自己实现的,也是Spring事务中最复杂的
  11. Spring事务的传播机制是基于数据库连接来做的,一个数据库连接一个事务,如果传播机制配置为需要新开一个事务,那么实际上就是先建立一个数据库连接,在此新数据库连接上执行sql

参考链接

第九部分 拦截器&过滤器(未完成)

一、拦截器

SpringMVC拦截器
  1. 步骤:
    • 用户发送请求,经过 前端控制器Dispacherservlet(Controller的核心)将url交给处理器映射器HandlerMapping处理
    • 处理器映射器HandlerMapping处理url,返回HandlerExecutionChain(可能包含拦截器,一定包含自定义的Controller(Handler))
    • 前端控制器Controller交给处理器适配器HandlerAdapter 处理,处理完成后,返回MV对象(ModelAndView)
    • 前端控制器将MV 交给视图控制器ViewResolver ,将MV 拆分成Model和View 两个对象,并且将model渲染到View视图上,并且将View返回给前端控制器
    • 最后,前端控制器将视图响应给用户。
  2. 实现原理:
    • 方式:(1)第一种是:要定义的 Interceptor 类要实现了Spring的HandlerInterceptor 接口;(2)第二种是:继承实现了HandlerInterceptor 接口的类

二、过滤器

参考链接

  1. https://blog.csdn.net/appandroid/article/details/106597142

第十部分 Mybatis

第十一部分 面试题

  1. Spring 框架中都用到了哪些设计模式?
    • 代理模式 — 在 AOP 和 remoting 中被用的比较多。
    • 单例模式 — 在 Spring 配置文件中定义的 Bean 默认为单例模式。
    • 模板方法 — 用来解决代码重复的问题。比如 RestTemplate、JmsTemplate、JdbcTemplate 。
    • 前端控制器 — Spring提供了 DispatcherServlet 来对请求进行分发。
    • 视图帮助(View Helper) — Spring 提供了一系列的 JSP 标签,高效宏来辅助将分散的代码整合在视图里。
    • 依赖注入 — 贯穿于 BeanFactory / ApplicationContext 接口的核心理念。
    • 工厂模式 — BeanFactory 用来创建对象的实例。
  2. Spring启动流程:(未完成)
    • 基本步骤:(1)获取、解析、注册配置信息,将配置的文件信息转换Map<name,beanDefinition>(bean定义注册表);(2)根据上述的Map<name,beanDefinition>去实例化bean,并完成以来注入
    • 详细步骤
  3. 哪些对象是由ioc管理的呢,举个例子

第十二部分 MiniSpring

一、IOC

mini_spring_生命周期

instantiation-strategy

xml-file-define-bean

  1. 每个类的作用和含义
    • BeanFactory:bean容器,内部包含一个map用以保存bean,只有获取bean的方法。
      1. ApplicationContext:spring中较之于BeanFactory更为先进的IOC容器,ApplicationContext除了拥有BeanFactory的所有功能外,还支持特殊类型bean,如上一节中的BeanFactoryPostProcessor和BeanPostProcessor的自动识别、资源加载、容器事件和监听器、国际化支持、单例bean自动初始化等
        • ConfigurableApplicationContext、AbstractApplicationContext、AbstractRefreshableApplicationContext、AbstractXmlApplicationContext、ClassPathXmlApplicationContext
        • 通过继承类实现功能:ListableBeanFactory、HierarchicalBeanFactory、ResourceLoader、ApplicationEventPublisher
    • BeanDefinition:用于定义bean信息的类,包含bean的class类型、构造参数、属性值等信息,每个bean对应一个BeanDefinition的实例。简化BeanDefinition仅包含bean的class类型。
      1. BeanDefinitionReader:读取bean定义信息的抽象接口
      2. AbstractBeanDefinitionReader:实现BeanDefinitionReader接口
      3. XmlBeanDefinitionReader:从xml文件中读取的实现类,实现AbstractBeanDefinitionReader抽象类
        • 包含BeanDefinitionRegistry和ResourceLoader:加载资源,并注册BeanDefinition
    • BeanDefinitionRegistry:BeanDefinition注册表接口,定义注册BeanDefinition的方法。
    • SingletonBeanRegistry:定义添加和获取单例bean的方法。其实现类为DefaultSingletonBeanRegistry,
    • DefaultListableBeanFactory:向bean容器中注册BeanDefinition后,使用bean时才会实例化。
      1. 作为BeanDefinitionRegistry和SingletonBeanRegistry的实现类,具备两者的能力。
      2. 定义了一个beanDefinitionMap保存beanDefinition
    • InstantiationStrategy:针对bean的实例化,抽象出一个实例化策略的接口,只有一个bean实例化方法,有两个实现类:
      1. SimpleInstantiationStrategy:使用bean的构造函数来实例化,反射机制constructor
      2. CglibSubclassingInstantiationStrategy:使用CGLIB动态生成子类(未实现)
    • PropertyValues:bean属性信息List,注入BeanDefinition,其中PropertyValue类代表bean的一个属性信息<name,value>
    • BeanReference:包装一个bean对另一个bean的引用。实例化beanA后填充属性时,若PropertyValue#value为BeanReference,引用beanB,则先去实例化beanB。在AbstractAutowireCapableBeanFactory中实现
    • BeanFactoryPostProcessor:spring提供的容器扩展机制,允许在bean实例化之前修改bean的定义信息即BeanDefinition的信息。
      1. PropertyPlaceholderConfigurer:用properties文件的配置值替换xml文件中的占位符
      2. CustomEditorConfigurer:实现类型转换。
    • BeanPostProcessor:spring提供的容器扩展机制,不同于BeanFactoryPostProcessor的是,BeanPostProcessor在bean实例化后修改bean或替换bean。是后面实现AOP的关键。
      1. InstantiationAwareBeanPostProcessor:继承BeanPostProcessor的接口
      2. AutowiredAnnotationBeanPostProcessor:实现InstantiationAwareBeanPostProcessor, BeanFactoryAware
      3. DefaultAdvisorAutoProxyCreator:实现InstantiationAwareBeanPostProcessor, BeanFactoryAware
    • InitializingBean、DisposableBean:初始化、销毁bean
      1. AbstractAutowireCapableBeanFactory、DefaultSingletonBeanRegistry
      2. 三种方法:
        • 在init-and-destroy-method.xml文件中配置方法,在BeanDefinition中增加属性initMethodName和destroyMethodName。
        • 继承自InitializingBean和DisposableBean
        • 在方法上加注解PostConstruct和PreDestroy
    • Aware接口:标记性接口,其实现子类能感知容器相关的对象。
      1. BeanFactoryAware:让其实现者感知所属的BeanFactory。
      2. ApplicationContextAware:让其实现者感知所属的ApplicationContext。
    • FactoryBean:一种特殊的bean,当向容器获取该bean时,容器不是返回其本身,而是返回其FactoryBean#getObject方法的返回值,可通过编码方式定义复杂的bean。
    • ApplicationEventMulticaster接口:注册监听器和发布事件的抽象接口
      1. AbstractApplicationEventMulticaster:抽象类
      2. SimpleApplicationEventMulticaster:实现类
    • Resource:资源的抽象和访问接口
      1. FileSystemResource:文件系统资源的实现类
      2. ClassPathResource:classpath下资源的实现类
      3. UrlResource:对java.net.URL进行资源定位的实现类
      4. ResourceLoader接口则是资源查找定位策略的抽象,DefaultResourceLoader是其默认实现类
    • AbstractApplicationContext:
      1. AbstractRefreshableApplicationContext、AbstractXmlApplicationContext、ClassPathXmlApplicationContext

二、AOP

  1. 每个类的作用和含义
    • AspectJExpressionPointcut:实现以下三个接口
      1. Pointcut :Pointcut是JoinPoint的表述方式,能捕获JoinPoint。PointCut需要同时匹配类和方法
      2. ClassFilter接口:匹配类
      3. MethodMatcher接口:匹配方法
    • AopProxy:获取代理对象的抽象接口
      1. JdkDynamicAopProxy:基于JDK动态代理的具体实现
      2. CglibAopProxy:与基于JDK的动态代理在运行期间为接口生成对象的代理对象不同,基于CGLIB的动态代理能在运行期间动态构建字节码的class文件,为类生成子类,因此被代理类不需要继承自任何接口。
      3. TargetSource:被代理对象的封装。
      4. ProxyFactory:AOP代理工厂,决定使用JDK动态代理还是CGLIB动态代理。
      5. MethodInterceptor:方法拦截器,可以拦截方法,可在被代理执行的方法前后增加代理行为。在AOP Alliance包中
      6. DefaultAdvisorAutoProxyCreator:处理横切逻辑的织入返回代理对象的InstantiationAwareBeanPostProcessor实现类,当对象实例化时,生成代理对象并返回。
    • Advisor:包含一个Pointcut和一个Advice的组合,Pointcut用于捕获JoinPoint,Advice决定在JoinPoint执行某种操作。
      1. AspectJExpressionPointcutAdvisor、PointcutAdvisor
      2. BeforeAdvice:定义MethodBeforeAdviceInterceptor拦截器,在执行被代理方法之前,先执行BeforeAdvice的方法。还存在AfterAdvice/AfterReturningAdvice/ThrowsAdvice
      3. AdvisedSupport:支持方法,包括代理类型,被代理对象封装,增强方法

三、解决循环依赖

  1. DefaultSingletonBeanRegistry

四、扩展

  1. PropertyPlaceholderConfigurer:在bean实例化之前,编辑BeanDefinition,解析XML文件中的占位符,然后用properties文件中的配置值替换占位符,继承自BeanFactoryPostProcessor。
  2. ClassPathBeanDefinitionScanner:扫描类组装BeanDefinition然后注册到容器中
  3. 注解@Value和@Autowired:通过BeanPostProcessor处理,AutowiredAnnotationBeanPostProcessor用于处理
  4. Converter、ConverterFactory、GenericConverter:类型转换器接口
    • Converter:将S类型的对象转换为T类型的对象,比如将String类型的对象转换为Integer类型的对象的实现类StringToIntegerConverter
    • ConverterFactory:适合一对多的类型转换,可以将一种类型转换为另一种类型及其子类。比如将String类型转换为Ineger/Long/Float/Double/Decimal等Number类型时,只需定义一个ConverterFactory转换器StringToNumberConverterFactory
    • GenericConverter:
    • ConversionService:类型转换体系的核心接口,将以上三种类型转换器整合到一起,GenericConversionService是其实现类
    • DefaultConversionService:GenericConversionService的基础上添加内置转换器
  5. ConversionServiceFactoryBean:创建ConversionService的FactoryBean
  6. 包扫描:扫描特定注解的类,提取类的相关信息组装成BeanDefinition注册到容器中
    • ClassPathScanningCandidateComponentProvider、ClassPathBeanDefinitionScanner

五、功能描述

  1. IOC实现:bean生命周期,解决循环依赖
    • bean实例化:BeanFactory、BeanDefinition、BeanDefinitionRegistry、SingletonBeanRegistry、DefaultSingletonBeanRegistry、DefaultListableBeanFactory、InstantiationStrategy、PropertyValues、InitializingBean、DisposableBean
    • 事件监听器:ApplicationEventMulticaster
    • 资源加载器:ClassPathResource、FileSystemResource、UrlResource
    • 循环依赖:
  2. AOP实现:动态代理实现
    • Pointcut、ClassFilter、MethodMatcher、AopProxy、TargetSource、ProxyFactory、BeforeAdvice、Advisor、DefaultAdvisorAutoProxyCreator
  3. 其他
    • 应用上下文:ApplicationContext
    • 类型转化:Converter、ConverterFactory、GenericConverter、ConversionService、GenericConversionService、DefaultConversionService
    • 容器扩展点:BeanFactoryPostProcessor、BeanPostProcessor

六、流程

  1. IOC:通过工厂自动获得用户需要的bean,一切装配都由bean容器执行
    • 使用BeanDefinitionReader读取xml配置文件,合成BeanDefinition
    • 在所有BeanDefintion加载完成后,但在bean实例化之前,使用BeanFactoryPostProcessor修改上一步得到的BeanDefinition
    • 使用BeanPostProcessor,在bean实例化后对于bean进行修改或者替换
    • 设置bean的属性:使用BeanDefinition的构造方法,传入PropertyValues
    • 执行BeanPostProcessor的前置处理
    • bean初始化,执行初始化方法
    • 执行BeanPostProcessor的后置处理
    • 使用bean,然后销毁bean,执行销毁方法
  2. AOP:生成代理对象调用服务方法

路线:spring、springmvc、springboot、springcloud

面试题

  1. 我把SpringIOC在源码层面从注册到生产bean,再到bean的生命周期讲了一遍(提到了很多扩展点,讲的比较细)
  2. 说AOP的时候,从解析切面,到创建动态代理说了下
posted @   汤十五  阅读(302)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示