一. spring是如何管理事务的
Spring提供的事务管理可以分为两类:
- 编程式;比较灵活,但是代码量大,存在重复的代码比较多
- 声明式;声明式的比编程式的更灵活方便。
1. 编程式事务
通过 Spring 提供的事务管理 API,我们可以在代码中灵活控制事务的执行
2. 声明式事务
声明式事务的两种实现方式
- XML文件中配置(
<tx>
命名空间) - 添加注解(@Transactional )
Spring 的声明式事务管理是建立在 Spring AOP 机制之上的,其本质是对目标方法前后进行拦截,并在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中作相关的事务规则声明(或通过等价的基于标注的方式),便可以将事务规则应用到业务逻辑中。总的来说,声明式事务得益于 Spring IoC容器 和 Spring AOP 机制的支持:IoC容器为声明式事务管理提供了基础设施,使得 Bean 对于 Spring 框架而言是可管理的;而由于事务管理本身就是一个典型的横切逻辑(正是 AOP 的用武之地),因此 Spring AOP 机制是声明式事务管理的直接实现者。
显然,声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要在XML文件中配置或者添加注解就可以获得完全的事务支持。因此,通常情况下,笔者强烈建议在开发中使用声明式事务,不仅因为其简单,更主要是因为这样使得纯业务代码不被污染,极大方便后期的代码维护。
推荐一篇关于Spring 事务的博客
Spring 事务管理机制概述
二. IOC(控制反转)/DI(依赖注入)
控制反转(Inversion of Control)和依赖注入(Dependecy Injection)是同一个概念,具体的讲:当某个角色需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者因此也称为依赖注入。IOC的作用:产生对象实例,它是基于工厂设计模式的
spring ioc中有三种依赖注入
- 接口注入;
- setter方法注入;
- 构造方法注入;
Spring IOC 自动绑定模式:
可以设置autowire按以下方式进行绑定
- 按byType只要类型一致会自动寻找,
- 按byName自动按属性名称进行自动查找匹配.
- @Autowired默认是ByType,如果想根据属性名注入,那么就再加上注解 @Resource(name=“属性名”))
Spring实现ioc控制反转描述:
-
原来需要我们自己进行bean的创建以及注入,而现在交给spring容器去完成bean的创建以及注入。
-
官方解释:控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
推荐一篇博客
深入浅出spring IOC中三种依赖注入方式
三. AOP(面向切面编程)
AOP是OOP 的延续
AOP(Aspect Oriented Programming)面向切面编程
OOP(Object-Oriented Programming)面向对象编程
AOP 主要应用于日志记录,性能统计,安全控制,事务处理(项目中使用的)等方面。
Spring中实现AOP的技术:
在Spring中可以通过代理模式来实现AOP
代理模式分为
- 静态代理:一个接口,分别有一个真实实现和一个代理实现。
- 动态代理:通过代理类的代理,接口和实现类之间可以不直接发生联系可以在运行期(Runtime)实现动态关联。
动态代理有两种实现方式(实现原理)
- 通过jdk的动态代理实现。基于接口生成目标类的代理对象进行方法增强,是java提供的动态代理机制,基于内存的java对象进行增强,jdk的动态代理必须要有接口的支持。
- 通过cglib来实现。基于当前类的目标类生成子类,从而增强方法,是字节码的增强技术。cglib不需要有接口的支持,它是基于类的。
spring对AOP的支持
- (1)如果目标对象实现了接口,默认会采用JDK的动态代理机制实现AOP
- (2)如果目标对象实现了接口,可以强制使用CGLIB实现AOP
- (3)如果目标对象没有实现接口,必须使用CGLIB生成代理,spring会自动在CGLIB和JDK动态代理之间切换
如何强制使用CGLIB生成代理?
- 添加CGLIB库,SPRING_HOME/lib/cglib/*.jar
- 在spring的配置文件中加入:
<aop:aspectj-autoproxy proxy-target-class=“true”/>
推荐文章:
Spring AOP 功能使用详解
spring用动态代理还是cglib?
Spring AOP事务的描述:
在spring-common.xml里通过<aop:config >
里面先设定一个表达式,设定对service里那些方法 如:对add* ,delete*,update*等开头的方法进行事务拦截。我们需要配置事务的传播(propagation=“REQUIRED”)特性,通常把增,删,改以外的操作需要配置成只读事务(read-only=“true”).只读事务可以提高性能。之后引入tx:advice,在tx:advice引用 transactionManager(事务管理),在事务管理里再引入sessionFactory,sessionFactory注入 dataSource,最后通过<aop:config >
引入txAdvice。