浅谈Spring | 青训营笔记

81 阅读10分钟

这是我参与「第四届青训营 」笔记创作活动的第 8 天。今天复习了一下Spring的相关知识。


Spring是一个开源容器框架,可以接管web层,业务层,dao层,持久层的组件,并且可以配置各种bean,和维护bean与bean之间的关系。

其核心就是控制反转(IOC),和面向切面(AOP),简单的说就是一个分层的轻量级开源框架。

相关概念

img

img

Spring是一个分层架构,由7个定义良好的模块组成

  1. Spring core:提供了spring 的核心功能,BeanFactory是spring核心容器的主要组件,它通过Ioc把程序的配置和依赖性与实际的代码分开,是整个spring的基础
  2. Spring context:通过配置文件向spring提供上下文信息,它构建在BeanFactory之上,另外增加了国际化和资源访问等功能
  3. Spring dao:提供了一个简单有效的JDBC应用
  4. Spring aop:提供了面向方面编程的功能
  5. Spring orm:spring除了有自己的JDBC以外还提供了对其他ORM框架的支持,如Hibernate,都可以和spring进行良好的结合
  6. Spring web:提供了简化的处理多部分请求以及把请求参数绑定到域的任务。
  7. Spring MVC:提供了MVC2模式的实现,也可以和struts良好的集成在一起。

Spring并没有为我们提供日志系统,我们需要使用AOP(面向方面编程)的方式,借助Spring与日志系统log4j实现我们自己的日志系统。

三大核心组件

  1. Core

  2. Context

  3. Beans(最核心)

    1. 调用Bean的方式

      1. 调用构造器
      2. 调用静态工厂方法
      3. 调用实例工厂方法

Bean五大作用域

作用域描述
singleton 单例模式在Spring Loc中仅存在一个Bean实例,Bean以单例的形式存在,bean的默认作用域
prototype 原型模式一个bean定义对应多个对象实例,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()。
request每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring WebApplicationContext环境。
session同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。 该作用域仅适用于web的Spring WebApplicationContext环境。
application限定一个Bean的作用域为ServletContext的生命周期。 该作用域仅适用于web的Spring WebApplicationContext环境。

注意点

  1. Web端特有的作用域:request 和 session是在Web开发才会存在

  2. Serlet作用域:

    1. Request域

    2. Session域

      1. 范围:即一个会话(客户打开一个浏览器,发出各种请求,直到最后关闭该窗口)
      2. 作用:用来保存数据,数据保存在服务器端(与Cookie的区别)
    3. ServletContext :

      1. 范围:包含该应用程序下所有的servlet和Request访问。
      2. 作用:实现数据的共享(一般为:数据库的url,密码,用户名等等)
    4. 额外:JSP的Page页面

      1. 范围:整个JSP页面

注意点

  1. Spring容器:

    1. 无需手动创建Spring容器:使用spring的web应用时,不用手动创建spring容器,而是通过配置文件声明式地创建spring容器。

    2. Bean

      1. bean同名问题:

        1. 一个应用程序中可以有多个spring容器 不同容器里的bean可以同名
        2. 但scope=application的时候,同名的bean只有一个
      2. Spring不但可以管理Bean,还可以管理Bean的生命周期、作用域

    3. Spring容器也叫IoC容器,本质上就是一个工厂。

IOC

是一种面向对象的设计思想,维护对象与对象之间的依赖关系,并且降低对象之间的耦合度。

注入方式

  1. 基于属性注入
  2. 就构造方法注入
  3. 基于setter注入

注解

  1. @autowired

    用于代表set方法,可以写在成员变量、set方法、构造器上。

    1. 属性

      1. required

        1. 作用:对象是否可以为空

          1. false,对象可以为null;
          2. true,对象必须存对象,不能为null,找不到会抛出异常。
    2. 注意点

      1. 只能根据类型注入Bean。
      2. 首先根据类型找到对应的Bean, 如果对应类型的 Bean 不是唯一的,那么就根据属性名称和Bean的名称进行匹配。如果匹配得上,就会使用该Bean;如果还无法匹配,就会抛出异常。
    3. @Resources

      1. 与@autowired

        1. 区别:

          1. 来源不同:@autowired 是Spring提供的,@resources由JDK提供(1.8后才有)
          2. 注入(装配)方式不同:@Autowired 默认按 byType 自动注入,不支持id匹配,(如果要,则需要加上@Qualifier注释); @Resource 默认按 byName 自动注入
        2. 相同点

          1. 属性:

            1. name 属性解析为 Bean 的名字
            2. type 属性则解析为 Bean 的类型。
          2. 都可以用来装配Bean

            1. 可以写在字段或者setter方法上
      2. 注意点:

        1. 匹配机制

          • 如有指定的name属性,先按该属性进行byName方式查找装配;
          • 其次再进行默认的byName方式进行装配;
          • 如果以上都不成功,则按byType的方式自动装配。
          • 都不成功,则报异常。
    4. @Quanlifier

      用于声明Bean的名称,

      1. 注意点

        1. 不能单独使用:需要加上value属性
        2. 补充:Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
    5. @Primary

      会通知 Ioc 容器优先使用它所标注的Bean进行注入。

      1. 注意点:

        1. @Primary可以在多个类上标注,那就会抛异常
  2. @Bean

    1. 作用:用于装配第三方Bean,适用于Bean
  3. 作用位置

    1. 注意点

      1. 需要在@Configuration注解下创建,但不是必须的它也可以出现在带有@Component注解的类中,甚至是普通的类中

AOP

Spring采用依赖注入的方式,实现了Ioc思想

术语解释

  1. 接入点(Join point) :程序执行的某个特定位置。 (一个类或者一段代码拥有一些具有边界性质的特定点)

    1. 例如:如一个类的初始化前后,或者类的某个方法调用前后、方法抛出异常后等等;
    2. 注意点:Spring仅支持方法的连接点,即仅能在方法调用前后、方法抛出异常时这些程序执行点织入增强。
  2. 切点(Pointcut) :切入点是一个连接点的过滤条件。

    1. UserService类中的所有方法实际上都是连接点,即连接点是程序类中客观存在的事物

    2. 注意点

      1. AOP通过切点(筛选条件)定位到特定的连接点
      2. 一个切点匹配多个连接点
      3. 每个类都拥有多个连接点
  3. 通知(Advice,又称"增强")

    1. 定义:切面在某个具体额连接点采取的行为或行动。 (即自己想要的功能,安全,事务,日志)
    2. 注意点:它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
  4. 通知器(Advisor)

    1. 定义:由一个切入点和一个通知组成。
  5. 切面(Aspect)

    1. 定义:同样是切点和通知组成。
    2. Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
  6. 引入(Introduction)

    1. 定义:允许我们向现有的类添加新方法属性。把切面(也就是新方法属性:通知定义的)用到目标类中吗
  7. 目标对象(Target object) :被通知的对象(方法)

  8. 代理(proxy) :向目标对象应用通知之后创建的对象(看"代理"本身的字面意思)

  9. 织入(Weaving)

    1. 把切面应用到目标对象来创建新的代理对象的过程。

    2. 注意点:

      1. Spring通过运行时的方式来创建新的代理对象

img

织入

织入是将增强添加对目标类具体连接点上的过程。AOP像一台织布机,将目标类、增强或引介通过AOP这台织布机天衣无缝地编织到一起

时间

  1. 编译期织入,这要求使用特殊的Java编译器。

  2. 类装载期织入,这要求使用特殊的类装载器。

  3. 动态代理织入,

    1. JDK动态代理(AOP默认使用)

      1. Java提供的动态代理技术,可以在运行时创建接口的代理实例
    2. GGLib动态代理,

      1. 采用底层的字节码技术,在运行时创建子类代理的实例
      2. 当目标对象不存在接口时,Spring AOP就会采用这种方式,在子类实例中织入代码。

注意点

  1. 运行时注入

    1. 需要为目标生成代理对象

通知类型

  1. 前置通知:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常。正常返回通知
  2. 后置通知:连接点正常执行完成后执行,如果连接点抛出异常,则不会执行。 异常返回通知
  3. 环绕通知:环绕通知围绕在连接点前后,比如一个方法调用的前后。这是最强大的通知类型,能在方法调用前后自定义一些操作。 环绕通知还需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行。
  4. 返回(最终)通知:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容。
  5. 异常通知:在目标方法抛出异常时执行的通知。

通知顺序

  1. 在目标方法没有抛出异常的情况下

    1. 前置通知
    2. 环绕通知的调用目标方法之前的代码
    3. 目标方法
    4. 环绕通知的调用目标方法之后的代码
    5. 后置通知
    6. 最终通知
  2. 在目标方法抛出异常的情况下

    1. 前置通知
    2. 环绕通知的调用目标方法之前的代码
    3. 目标方法
    4. 抛出异常
    5. 异常通知
    6. 最终通知

注解

  1. @Controller

  1. BeanFactory和FactoryBean

    1. BeanFactory

      1. 工厂Bean,是一个Bean,作用是产生其他bean 实例

      2. 作用

        1. 产生其他bean 实例,实现单例模式
        2. 提供一个工厂方法,该方法用来返回其他Bean 实例
      3. 方法:

        1. getBean(string name):从Spring容器中获取对应Bean对象的方法
        2. containsBean(String name)::用于判断Spring容器中是否存在该对象
        3. isSingleton(String name):用于判断Bean对象是否为单例对象。
      4. 注意

        1. 通常情况下,Bean 无须自己实现工厂模式,Spring 容器担任工厂角色
        2. 但少数情况下,容器中的Bean 本身就是工厂,其作用是产生其它Bean 实
    2. FactoryBean

      1. Bean 工厂,是一个工厂(Factory)

      2. 顶层接口:Spring IOC 容器的最顶层接口就是这个

      3. 作用

        1. 管理Bean
        2. 即实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
  2. ApplicationContext

    1. 作用:提供框架的实现,包括BeanFactory的所有功能
  3. BeanWrapper

    1. 作用:提供统一的get以set方法,对Bean的包装
  4. 其他

    1. SpringFactoriesLoader

      1. 该类并不对外暴露给应用开发者使用,而是Spring框架自己使用的内部工具类,本身被声明为抽象类(abstract),不可以被实例化。

\