回顾Spring(二)

隐身守侯 提交于 2020-02-26 03:52:50

动态代理

代理设计模式的原理:使用一个代理将原本对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。

动态代理的方式

  1. 基于接口实现动态代理: JDK动态代理
  2. 基于继承实现动态代理: CglibJavassist动态代理

 

AOP概述

  1. AOP(Aspect-Oriented Programming面向切面编程):是一种新的方法论,是对传 OOP(Object-Oriented Programming,面向对象编程)的补充。
  2. AOP编程操作的主要对象是切面(aspect),而切面用于模块化横切关注点(公共功能)
  3. 在应用AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能应用在哪里,以什么方式应用,并且不必修改受影响的类。这样一来横切关注点就被模块化到特殊的类里——这样的类我们通常称之为切面
  4. AOP的好处:
  •  每个事物逻辑位于一个位置,代码不分散,便于维护和升级
  • 业务模块更简洁,只包含核心业务代码
  • AOP图解

AOP术语

横切关注点:从每个方法中抽取出来的同一类非核心业务。

切面(Aspect):封装横切关注点信息的类,每个关注点体现为一个通知方法。

通知(Advice):切面必须要完成的各个具体工作

目标(Target):被通知的对象

代理(Proxy):向目标对象应用通知之后创建的代理对象

连接点(Joinpoint):横切关注点在程序代码中的具体体现,对应程序执行的某个特定位置。例如:类某个方法调用前、调用后、方法捕获到异常后等。

切入点(pointcut):定位连接点的方式。每个类的方法中都包含多个连接点,所以连接点是类中客观存在的事物。

AspectJ

AspectJJava社区里最完整最流行的AOP框架。Spring2.0以上版本中,可以使用基于AspectJ注解或基于XML配置的AOP

1.Spring中启用AspectJ注解支持

1.导入JAR

  • com.springsource.net.sf.cglib-2.2.0.jar
  • com.springsource.org.aopalliance-1.0.0.jar
  • com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar 
  • spring-aop-4.0.0.RELEASE.jar
  • spring-aspects-4.0.0.RELEASE.jar
  •  

2.引入aop名称空间

3.配置

<aop:aspectj-autoproxy>

         当Spring IOC容器侦测到bean配置文件中的<aop:aspectj-autoproxy>元素时,会自动为    AspectJ切面匹配的bean创建代理

2.AspectJ注解声明切面

  1. 要在Spring中声明AspectJ切面,只需要在IOC容器中将切面声明为bean实例。
  2. 当在Spring IOC容器中初始化AspectJ切面之后,Spring IOC容器就会为那些与 AspectJ切面相匹配的bean创建代理。
  3. AspectJ注解中,切面只是一个带有@Aspect注解的Java类,它往往要包含很多通知。
  4. 通知是标注有某种注解的简单的Java方法。
  5. AspectJ支持5种类型的通知注解:
  • @Before:前置通知,在方法执行之前执行
  • @After:后置通知,在方法执行之后执行
  • @AfterRunning:返回通知,在方法返回结果之后执行
  • @AfterThrowing:异常通知,在方法抛出异常之后执行
  • @Around:环绕通知,围绕着方法执行

AOP细节

切入点表达式的语法格式

execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名]([参数列表]))

  <!-- 【拦截所有public方法】 -->
       <aop:pointcut expression="execution(public * *(..))" id="pt"/>

       <!-- 【拦截所有save开头的方法 】 -->
       <aop:pointcut expression="execution(* save*(..))" id="pt"/>

       <!-- 【拦截指定类的指定方法, 拦截时候一定要定位到方法】 -->
       <aop:pointcut expression="execution(public * cn.itcast.g_pointcut.OrderDao.save(..))" id="pt"/>

       <!-- 【拦截指定类的所有方法】 -->
       <aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.*(..))" id="pt"/>

       <!-- 【拦截指定包,以及其自包下所有类的所有方法】 -->
       <aop:pointcut expression="execution(* cn..*.*(..))" id="pt"/>

       <!-- 【取非值】 -->
       <aop:pointcut expression="!execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>

切入点表达式应用到实际的切面类中

事务

JavaEE企业级开发的应用领域,为了保证数据的完整性一致性,必须引入数据库事务的概念,所以事务管理是企业级应用程序开发中必不可少的技术。

事务就是一组由于逻辑上紧密关联而合并成一个整体(工作单元)的多个数据库操作,这些操作要么都执行要么都不执行

事务的四个关键属性(ACID):

原子性(atomicity)原子的本意是不可再分,事务的原子性表现为一个事务中涉及到的多个操作在逻辑上缺一不可。事务的原子性要求事务中的所有操作要么都执行,要么都不执行。

一致性(consistency)一致指的是数据的一致,具体是指:所有数据都处于满足业务规则的一致性状态。一致性原则要求:一个事务中不管涉及到多少个操作,都必须保证事务执行之前数据是正确的,事务执行之后数据仍然是正确的。如果一个事务在执行的过程中,其中某一个或某几个操作失败了,则必须将其他所有操作撤销,将数据恢复到事务执行之前的状态,这就是回滚

隔离性(isolation):在应用程序实际运行过程中,事务往往是并发执行的,所以很有可能有许多事务同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。隔离性原则要求多个事务在并发执行过程中不会互相干扰

 ④持久性(durability):持久性原则要求事务执行完成后,对数据的修改永久的保存下来,不会因各种系统错误或其他意外情况而受到影响。通常情况下,事务对数据的修改应该被写入到持久化存储器中。

Spring提供的事务管理器

  • Spring从不同的事务管理API中抽象出了一整套事务管理机制,让事务管理代码从特定的事务技术中独立出来。开发人员通过配置的方式进行事务管理,而不必了解其底层是如何实现的。
  • Spring的核心事务管理抽象是它为事务管理封装了一组独立于技术的方法。无论使用Spring的哪种事务管理策略(编程式或声明式),事务管理器都是必须的。
  • 事务管理器可以以普通的bean的形式声明在Spring IOC容器中。

事务管理器的主要实现

  1. DataSourceTransactionManager:在应用程序中只需要处理一个数据源,而且通过JDBC存取。
  2. JtaTransactionManager:在JavaEE应用服务器上用JTA(Java Transaction API)进行事务管理
  3. HibernateTransactionManager:用Hibernate框架存取数据库

事务的传播行为

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。

事务的传播行为可以由传播属性指定。Spring定义了7种类传播行为。

事务传播属性可以在@Transactional注解的propagation属性中定义。

事务的隔离级别

数据库并发问题

         假设现在有两个事务:Transaction01Transaction02并发执行。

  1. 脏读

         ①Transaction01将某条记录的AGE值从20修改为30

         ②Transaction02读取了Transaction01更新后的值:30

         ③Transaction01回滚,AGE值恢复到了20

         ④Transaction02读取到的30就是一个无效的值。

2.不可重复读

         ①Transaction01读取了AGE值为20

         ②Transaction02AGE值修改为30

         ③Transaction01再次读取AGE值为30,和第一次读取不一致。

  1. 幻读

         ①Transaction01读取了STUDENT表中的一部分数据。

         ②Transaction02STUDENT表中插入了新的行。

         ③Transaction01读取了STUDENT表时,多出了一些行。

隔离级别

数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。

1.读未提交READ UNCOMMITTED

允许Transaction01读取Transaction02未提交的修改。

2.读已提交READ COMMITTED

            要求Transaction01只能读取Transaction02已提交的修改。

3.可重复读REPEATABLE READ

            确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。

4.串行化SERIALIZABLE

            确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。

5.各个隔离级别解决并发问题的能力见下表

 

脏读

不可重复读

幻读

READ UNCOMMITTED

READ COMMITTED

REPEATABLE READ

SERIALIZABLE

6.各种数据库产品对事务隔离级别的支持程度

 

Oracle

MySQL

READ UNCOMMITTED

false

true

READ COMMITTED

true(默认)

true

REPEATABLE READ

false

true(默认)

SERIALIZABLE

true true

 

Spring中指定事务隔离级别

  1. 注解

@Transactional注解声明式地管理事务时可以在@Transactionalisolation属性中设置隔离级别

  1. XML

Spring 2.x事务通知中,可以在<tx:method>元素中指定隔离级别

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!