Spring学习笔记

来源:互联网 发布:淘宝图片如何搬家 编辑:程序博客网 时间:2024/06/07 07:08

主要从W3Cshool摘抄.网址为https://www.w3cschool.cn/wkspring/pesy1icl.html 比这篇详细多了

简介

Spring作者

Rod Johnson

依赖注入(DI)

依赖注入是控制反转(IoC)的一种模式.依赖注入将项目中的java类粘合在一起,并在同一时间让他们保持独立.

对于两个类,依赖是指类A依赖于类B,注入是指类B将通过IoC呗注入到类B中.依赖注入可以以向构造函数传递参数的方式发生,或通过seeter方法post-construction.

面向方面的程序设计(AOP)

Spring框架的一个关键组件是面向方向的程序设计.AOP模块提供了面向方面的程序设计实现,允许定义拦截器方法和切入点.

Spring IoC容器

Io容器

Spring容器是Spring框架的核心.创建对象,将他们连接在一起,配置他们,管理他们的生命周期,都是这个容器管理的.Spring容器使用依赖注入来管理组件,这些对象成为Spring Beans.Spring IoC容器利用Java的POJO类和配置元数据(XML,Java注释,Java代码)来生成完全配置和可执行的系统或应用程序.

Spring BeanFactory容器

一个最简单的容器,主要功能是为依赖注入(DI)提供支持,Spring中有大量对BeanFactoryj接口的实现,XmlBeanFactory类最常用(从一个XML文件中读取配置元数据)

Spring ApplicationContext容器

Application Context是spring中较高级的一个容器.和BeanFactory类似,可以加载配置文件中定义的bean,将所有的bean集中在一起,当有请求的时候分配bean.还有企业所需的功能,如属性文件从解析文本信息和将事件传递给所指定的监听器.

ApplicationContext包含BeanFactory所有的功能,更强大.下面是常用的ApplicationContext接口实现:

  • FileSystemXmlApplicationContext:从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径
  • ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件.
  • WebXmlApplicationContext:会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean.

Spring Bean 定义

bean对象是构成应用程序的支柱,也是由Spring IoC容器管理的.bean是一个被实例化,组装,并通过Spring IoC容器所管理的对象.这些bean是通过容器提供的元数据创建的.

在XML的表单中的定义.beach定义中包含配置元数据的信息:

  • 如何创建bean
  • bean的生命周期
  • bean的依赖关系

Spring 配置元数据

Spring IoC容器完全由实际编写的配置元数据的格式解耦.Spring通过三种放大提供元数据:

  • XML配置文件
  • 注解的配置
  • Java的配置

Spring Bean 作用域

Bean有五种作用域:

  • gingleton(默认):该作用域将 bean 的定义的限制在每一个 Spring IoC 容器中的一个单一实例.
  • prototype:该作用域将单一 bean 的定义限制在任意数量的对象实例.
  • request:该作用域将 bean 的定义限制为 HTTP 请求。只在 web-aware Spring ApplicationContext 的上下文中有效.
  • session:该作用域将 bean 的定义限制为 HTTP 会话。 只在web-aware Spring ApplicationContext的上下文中有效.
  • global-session:该作用域将 bean 的定义限制为全局 HTTP 会话。只在 web-aware Spring ApplicationContext 的上下文中有效.

Spring Bean 生命周期

Bean也是存在生命周期的,他需要被初始化和销毁.为了定义安装和拆卸一个 bean,我们只要声明带有 init-method 和/或 destroy-method 参数的 。init-method 属性指定一个方法,在实例化 bean 时,立即调用该方法。同样,destroy-method 指定一个方法,只有从容器中移除 bean 之后,才能调用该方法。

如果存在太多具有相同名称的初始化或者销毁方法的Bean,可以在框架使用元素中的default-init-method 和 default-destroy-method属性来提供初始化和销毁方法.

Spring Bean 后置处理器

BeanPostProcessor接口定义回调方法,可以实现该方法来提供自己的实例化逻辑,依赖解析逻辑等.也可以在Spring容器通过插入一个或多个BeanPostPeocesser的实现来完成实例化,配置和初始化一个Bean之后实现一些自定义逻辑回调方法.

BeanPostProcessor 可以对 bean(或对象)实例进行操作,这意味着 Spring IoC 容器实例化一个 bean 实例,然后 BeanPostProcessor 接口进行它们的工作。

postProcessBeforeInitialization()和postProcessAfterInitialization()是两个主要方法,分别在初始化之前和初始化完成之后运行.

Spring Bean 定义继承

子Bean的定义继承父定义的配置数据,子定义可以根据需要重谢一些值,或者添加其他值.Bean定义的继承和Java类的继承无关,但是概念是相似的.Bean通过设定parent属性来指定父Bean.

Spring 依赖注入(DI)

编写复杂的Java应用程序时,应用程序类应该尽可能独立于其他Java类来增加这些类重用的可能性,并且单元测试的时候,测试类独立于其他类的独立性.依赖注入将这些类粘合在一起,同时使他们保持独立.

Spring 基于构造函数的依赖注入

当容器调用带有一组参数的类构造函数时,基于构造函数的DI就完成了,其中每个参数代表一个对其他类的依赖.

Spring 基于设值函数的依赖注入

当容器调用一个无参数的构造函数或者一个无参数的静态Factory方法来初始化你的bean后,通过容器在你的bean上调用设值函数,基于设值函数的DI就完成了.

Spring 注入内部Bean

inner beans 是在其他 bean 的范围内定义的 bean。因此在 或 元素内 元素被称为内部bean.

  • 普通Bean:在其他bean实例引用时,都引用同一个实例
  • 内部bean:每次引用时都是新创建的实例

Spring 注入集合

Java Bean提供了四种类型的集合配置元素,分别是:

  • list:对应List的注入
<property name="变量名">    <list>        <value>INDIA</value>        <value>Pakistan</value>        <value>USA</value>        <value>USA</value>     </list><property name="变量名">
  • set:对应Set的注入
<property name="变量名">     <set>        <value>INDIA</value>        <value>Pakistan</value>        <value>USA</value>        <value>USA</value>    </set><property name="变量名">
  • map:对用Map的注入
<property name="变量名">     <map>        <entry key="1" value="INDIA"/>        <entry key="2" value="Pakistan"/>        <entry key="3" value="USA"/>        <entry key="4" value="USA"/>     </map><property name="变量名">
  • props:对应 Properties的注入
<property name="变量名">     <props>        <prop key="one">INDIA</prop>        <prop key="two">Pakistan</prop>        <prop key="three">USA</prop>        <prop key="four">USA</prop>     </props><property name="变量名">

Spring Beans 自动装配

Spring容器可以在不使用和元素的情况下自动装配相互协作的bean之间的关系.

自动装配模式

下列自动装配模式,他们可以用于只是Spring容器来为使用自动装配进行依赖注入.可以使用bean元素的autowire属性为一个bean定义指定自动装配模式.

  • no:这是默认的设置,它意味着没有自动装配
  • byName:由属性名自动装配。Spring 容器看到在 XML 配置文件中 bean 的自动装配的属性设置为 byName。然后尝试匹配,并且将它的属性与在配置文件中被定义为相同名称的 beans 的属性进行连接。
  • byType:由属性数据类型自动装配。Spring 容器看到在 XML 配置文件中 bean 的自动装配的属性设置为 byType。然后如果它的类型匹配配置文件中的一个确切的 bean 名称,它将尝试匹配和连接属性的类型。如果存在不止一个这样的 bean,则一个致命的异常将会被抛出。
  • constructor:类似于 byType,但该类型适用于构造函数参数类型。如果在容器中没有一个构造函数参数类型的 bean,则一个致命错误将会发生。
  • autodeletect: Spring首先尝试通过 constructor 使用自动装配来连接,如果它不执行,Spring 尝试通过 byType 来自动装配。

自动装配的局限性

自动装配始终在同一个项目中使用,他的效果最好.但是他可能会使开发人员混淆的使用它来链接只有一个或者两个bean定义,不过,自动装配可以显著减少需要指定的属性或构造器参数.

Spring 自动装配 ‘byName’

在XML配置文件中beans的auto-wire属性设置为byName.然后,它尝试将属性与配置文件中定义为相同名称的beans进行匹配和连接,找到匹配项,并注入,否则抛出异常.

Spring 自动装配 ‘byType’

在 XML 配置文件中 beans 的 autowire 属性设置为 byType。然后,如果它的 type 恰好与配置文件中 beans 名称中的一个相匹配,它将尝试匹配和连接它的属性。如果找到匹配项,它将注入这些 beans,否则,它将抛出异常。

构造函数自动装配

在 XML 配置文件中 beans 的 autowire 属性设置为 constructor。然后,它尝试把它的构造函数的参数与配置文件中 beans 名称中的一个进行匹配和连线。如果找到匹配项,它会注入这些 bean,否则,它会抛出异常.

Spring 基于注释的配置

Spring 2.5就开始可以使用注释来配置依赖注入.可以使用相关类,方法或字段声明的注解,将bean配置移动到组件类本身.

  • @Required: 应用于bean属性的setter方法
  • @Autowired: 应用于bean属性的setter方法,非setter方法,构造函数和属性
  • @Qualifier: 通过指定确切的将被连线的bean,@Autowired 和 @Qualifier注解可以用来删除混乱.
  • JSR-250 Annotations: Spring支持JSR-250 的基础的注解,其中包括了 @Resource, @PostConstruct 和@preDestory 注解

Spring @Required 注释

@Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常

Spring @Autowired注释

@Autowired 注释对在哪里和如何完成自动连接提供了更多的细微的控制。
@Autowired 注释可以在 setter 方法中被用于自动连接 bean

setter方法中的 @Autowired

你可以在 XML 文件中的 setter 方法中使用 @Autowired 注释来除去 元素。当 Spring遇到一个在 setter 方法中使用的 @Autowired 注释,它会在方法中视图执行 byType 自动连接。

属性中的 @Autowired

你可以在属性中使用 @Autowired 注释来除去 setter 方法。当时使用 为自动连接属性传递的时候,Spring 会将这些传递过来的值或者引用自动分配给那些属性。

构造函数中的 @Autowired

你也可以在构造函数中使用 @Autowired。一个构造函数 @Autowired 说明当创建 bean 时,即使在 XML 文件中没有使用 元素配置 bean ,构造函数也会被自动连接。

@Autowired 的(required=false)选项

默认情况下,@Autowired 注释意味着依赖是必须的,它类似于 @Required 注释,然而,你可以使用 @Autowired 的 (required=false) 选项关闭默认行为。

Spring @Qualifier 注释

当创建多个具有相同类型的bean时,并且想要用一个属性只为它们其中的一个进行装配,在这种情况下,你可以使用 @Qualifier 注释和 @Autowired 注释通过指定哪一个真正的 bean 将会被装配来消除混乱.

Spring JSR-250注释

@PostConstruct 和 @PreDestroy 注释

为了定义一个 bean 的安装和卸载,我们使用init-method和/或destroy-method参数简单的声明一下.init-method 属性指定了一个方法,该方法在 bean的实例化阶段会立即被调用.同样地,destroy-method指定了一个方法,该方法只在一个 bean 从容器中删除之前被调用.

你可以使用 @PostConstruct 注释作为初始化回调函数的一个替代,@PreDestroy注释作为销毁回调函数的一个替代.

@Resource注释

你可以在字段中或者 setter 方法中使用 @Resource 注释,它和在 Java EE 5 中的运作是一样的。@Resource 注释使用一个 ‘name’ 属性,该属性以一个 bean 名称的形式被注入.你可以说,它遵循 by-name 自动连接语义.

Spring基于Java的配置

@Configuration 和 @Bean注解

带有 @Configuration 的注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源。@Bean 注解告诉 Spring,一个带有 @Bean 的注解方法将返回一个对象,该对象应该被注册为在 Spring 应用程序上下文中的 bean.

@Import 注解

@import 注解允许从另一个配置类中加载 @Bean 定义.

Spring 中的事件处理

Spring的核心是ApplicationContext,它负责管理beans的完整生命周期.当加载beans时,ApplicationContext发布某些类型的事件,如上下文启动时发布ContextstartedEvent,上下文停止时发布ContextStopedEvent.
通过ApplicationEvent类和APplicationListener接口来提供在ApplicationContext中处理事件,如果一个bean实现ApplicationListener,那么每次ApplicationEvent被发布到ApplicationContext上,那个bean会被通知.

Spring提供了以下的标准事件

  • ContextRefreshedEvent: ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext 接口中使用 refresh() 方法来发生。
  • ContextStartedEvent:当使用 ConfigurableApplicationContext 接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序。
  • ContextStoppedEvent:当使用 ConfigurableApplicationContext 接口中的 stop() 方法停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作。
  • ContextClosedEvent:当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。
  • RequestHandledEvent:这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。

Spring的事件处理是单线程的,多以如果一个事件被发布,只是直至并且除非所有的接受者得到的该消息,该进程被阻塞并且流程不会继续下去.如果事件被处理,应该在程序设计时注意这点.

监听上下文事件

为了监听上下文事件,一个 bean 应该实现只有一个方法 onApplicationEvent() 的 ApplicationListener 接口.

Spring 框架的AOP

Spring框架的一个关键组件是面向方面的编程(AOP)框架.面向方面的编程需要把程序逻辑分解成不同的部分称为所谓的关注点.跨一个应用程序的多个点的功能被称为横切关注点,这些横切关注点在概念上独立于应用程序的业务逻辑.

在oop中,关键单元模块度是类,而在AOP中单元模块度是方面.依赖注入帮助应程序相互解耦和AOP从他们所影响的对象中对横切关注点解耦.Spring AOP模块提供拦截器来拦截一个应用程序,可以再执行方法之前或者之后添加额外的功能.

AOP术语

项 描述 Aspect 一个模块具有一组提供横切需求的 APIs。例如,一个日志模块为了记录日志将被 AOP 方面调用。应用程序可以拥有任意数量的方面,这取决于需求。 Join point 在你的应用程序中它代表一个点,你可以在插件 AOP 方面。你也能说,它是在实际的应用程序中,其中一个操作将使用 Spring AOP 框架。 Advice 这是实际行动之前或之后执行的方法。这是在程序执行期间通过 Spring AOP 框架实际被调用的代码。 Pointcut 这是一组一个或多个连接点,通知应该被执行。你可以使用表达式或模式指定切入点正如我们将在 AOP 的例子中看到的。 Introduction 引用允许你添加新方法或属性到现有的类中。 Target object 被一个或者多个方面所通知的对象,这个对象永远是一个被代理对象。也称为被通知对象。 Weaving Weaving 把方面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时,类加载时和运行时完成。

通知的类型

通知 描述 前置通知 在一个方法执行之前,执行通知。 后置通知 在一个方法执行之后,不考虑其结果,执行通知。 返回后通知 在一个方法执行之后,只有在方法成功完成时,才能执行通知。 抛出异常后通知 在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。 环绕通知 在建议方法调用之前和之后,执行通知。

实现自定义方面

方法 描述 XML Schema based 方面是使用常规类以及基于配置的 XML 来实现的。 @AspectJ based @AspectJ 引用一种声明方面的风格作为带有 Java 5 注释的常规 Java 类注释。

Spring事务管理

事务是指一些操作要么完整的执行,要吗完全不执行,事务有四个关键特性,满足就能够说成是ACID:

  • 原子性 : 事务应该当作一个单独单元的操作,这意味着整个序列操作要么是成功,要么是失败的.
  • 一致性: 这表示数据库的引用完整性的一致性,表中唯一的主键等
  • 隔离性: 可能同时处理很多有相同的数据集的事务,每个事务应该与其他事务隔离,以防止数据损坏.
  • 持久性: 一个事务一旦完成全部操作后,这个事务的结果必须是永久性的,不能因系统故障而从数据库中删除.

Spring 框架在不同的底层事务管理 APIs 的顶部提供了一个抽象层。Spring 的事务支持旨在通过添加事务能力到 POJOs 来提供给 EJB 事务一个选择方案。Spring 支持编程式和声明式事务管理。EJBs 需要一个应用程序服务器,但 Spring 事务管理可以在不需要应用程序服务器的情况下实现。

局部事物 vs. 全局事务

局部事务是特定于一个单一的事务资源,如一个 JDBC 连接,而全局事务可以跨多个事务资源事务,如在一个分布式系统中的事务。

编程式 vs. 声明式

Spring支持两种类型的事务管理

  • 编程式事务管理 : 这意味着你在编程的帮助下有管理事务。这给了你极大的灵活性,但却很难维护。
  • 声明式事务管理 : 这意味着你从业务代码中分离事务管理。你仅仅使用注释或 XML 配置来管理事务。

声明式事务管理比编程式事务管理更可取,尽管它不如编程式事务管理灵活,但它允许你通过代码控制事务。但作为一种横切关注点,声明式事务管理可以使用 AOP 方法进行模块化。Spring 支持使用 Spring AOP 框架的声明式事务管理。

Spring事务抽象

Spring 事务抽象的关键是由 org.springframework.transaction.PlatformTransactionManager 接口定义:

  • TransactionStatus getTransaction(TransactionDefinition definition) : 根据指定的传播行为,该方法返回当前活动事务或创建一个新的事务
  • void commit(TransactionStatus status) : 该方法提交给定的事务和关于它的状态
  • void rollback(TransactionStatus status) : 该方法执行一个给定事务的回滚

TransactionDefinition 是在 Spring 中事务支持的核心接口:

  • int getPropagationBehavior() : 该方法返回传播行为。Spring 提供了与 EJB CMT 类似的所有的事务传播选项
  • int getIsolationLevel() : 该方法返回该事务独立于其他事务的工作的程度
  • String getName() : 该方法返回该事务的名称
  • int getTimeout() : 该方法返回以秒为单位的时间间隔,事务必须在该时间间隔内完成
  • boolean isReadOnly() : 该方法返回该事务是否是只读的

隔离级别的可能值:

  • TransactionDefinition.ISOLATION_DEFAULT : 这是默认的隔离级别
  • TransactionDefinition.ISOLATION_READ_COMMITTED : 表明能够阻止误读;可以发生不可重复读和虚读
  • TransactionDefinition.ISOLATION_READ_UNCOMMITTED : 表明可以发生误读、不可重复读和虚读
  • TransactionDefinition.ISOLATION_REPEATABLE_READ : 表明能够阻止误读和不可重复读;可以发生虚读
  • TransactionDefinition.ISOLATION_SERIALIZABLE : 表明能够阻止误读、不可重复读和虚读

传播类型的可能值:

  • TransactionDefinition.PROPAGATION_MANDATORY : 支持当前事务;如果不存在当前事务,则抛出一个异常
  • TransactionDefinition.PROPAGATION_NESTED : 如果存在当前事务,则在一个嵌套的事务中执行
  • TransactionDefinition.PROPAGATION_NEVER : 不支持当前事务;如果存在当前事务,则抛出一个异常
  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED : 不支持当前事务;而总是执行非事务性
  • TransactionDefinition.PROPAGATION_REQUIRED : 支持当前事务;如果不存在事务,则创建一个新的事务
  • TransactionDefinition.PROPAGATION_REQUIRES_NEW : 创建一个新事务,如果存在一个事务,则把当前事务挂起
  • TransactionDefinition.PROPAGATION_SUPPORTS : 支持当前事务;如果不存在,则执行非事务性
  • TransactionDefinition.TIMEOUT_DEFAULT : 使用默认超时的底层事务系统,或者如果不支持超时则没有

TransactionStatus 接口为事务代码提供了一个简单的方法来控制事务的执行和查询事务状态

  • boolean hasSavepoint() : 该方法返回该事务内部是否有一个保存点,也就是说,基于一个保存点已经创建了嵌套事务
  • boolean isCompleted() : 该方法返回该事务是否完成,也就是说,它是否已经提交或回滚
  • boolean isNewTransaction() : 在当前事务时新的情况下,该方法返回 true
  • boolean isRollbackOnly() : 该方法返回该事务是否已标记为 rollback-only
  • void setRollbackOnly() : 该方法设置该事务为 rollback-only 标记

Spring Web MVC框架

Spring web MVC 框架提供了模型-试图-控制的体系结构和可以用来开发灵活,松散解耦的web应用程序的组件.MVC模式导致了应用程序的不同方面的分离,同时提供了在这些元素之间的松散解耦.

  • 模型封装了应用程序数据,并且通常他们由POJO组成
  • 视图主要用于呈现模型数据,并且通常它生成客户端的浏览器可以解释的HTML输出
  • 控制器主要用于处理用户请求,并且构建合适的模型并将其传递到视图呈现