Spring是分层的 Java SE/EE 应用 full-stack轻量级开源框架,以IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展示层SpringMVC和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。html
用户也没必要再为单例模式类、属性文件解析等这些很底层的需求编写代码,能够更专一于上层的应用。spring
经过Spring提供的 IoC 容器,能够将对象间的依赖关系交由 Spring 进行控制,避免硬编码所形成的过分程序耦合。sql
spring方便解耦的实现代码:数据库
ContextStartedEvent:ApplicationContext启动后触发的事件ContextStoppedEvent:ApplicationContext中止后触发的事件ContextRefreshedEvent:ApplicationContext初始化或刷新完成后触发的事件ContextClosedEvent:ApplicationContext关闭后触发的事件 · 在tomcat中ContextRefreshedEvent 可能会触发两次,SpringBoot中只触发一次
AOP便是面向切面编程,是对OOP面向对象编程的补充和完善。express
实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引用特色的语法建立“方面”,从而使能够在编译期间织入有关“方面”的代码。编程
AOP的使用场景:权限,缓存,日志记录,事务,性能优化,异常处理。缓存
经过Spring的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能能够经过AOP 轻松应付。tomcat
spring AOP编程支持的实现代码:性能优化
开发步骤: (1):先引入aop相关的jar文件 spring-aop-3.2.5.RELEASE.jar【去spring3.2源码里面找】 aopalliance.jar【去spring2.5源码/lib/aopalliance文件里面找】 aspectjweaver.jar【去spring2.5源码/lib/aspectj文件里面找】或者【aspectj-1.8.2/lib/aspectjweaver.jar】 aspectjrt.jar【去spring2.5源码/lib/aspectj文件里面找】或者【aspectj-1.8.2/lib/aspectjrt.jar】 《注意:用到的spring2.5版本的jar本舰,若是用jd1.7版本可能会出现问题, 须要升级如下aspectj组件,即便用aspectj-1.8.2版本中提供的jar文件aspectjweaver.jar和aspectjrt.jar》 (2)bean.xml中引入aop名称空间 技巧:找到文件 spring-framework-3.2.5.RELEASE/docs/spring-framework-reference/htmlsingle 打开index.html搜索xmlns:aop而后找到下面红色三句话,分别拷贝到bean.xml中 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
能够将咱们从单调烦闷的事务管理代码中解脱出来,经过声明式方式灵活的进行事务的管理,提升开发效率和质量。app
声明式事务管理创建在AOP之上的。其本质是对方法先后进行拦截,而后在目标方法开始以前建立或者加入一个事务,在执行完目标方法以后根据执行状况提交或者回滚事务。
声明式:使用TransactionProxyFactoryBean:
围绕Poxy的动态代理可以自动的提交和回滚事务
org.springframework.transaction.interceptor.TransactionProxyFactoryBean
PROPAGATION_REQUIRED–支持当前事务,若是当前没有事务,就新建一个事务。这是最多见的选择。
PROPAGATION_SUPPORTS–支持当前事务,若是当前没有事务,就以非事务方式执行。
spring声明式事务的支持的实现代码:
<!-- <tx:advice>定义事务通知,用于指定事务属性,其中“transaction-manager”属性指定事务管理器,并经过<tx:attributes>指定具体须要拦截的方法 <tx:method>拦截方法,其中参数有: name:方法名称,将匹配的方法注入事务管理,可用通配符 propagation:事务传播行为, isolation:事务隔离级别定义;默认为“DEFAULT” timeout:事务超时时间设置,单位为秒,默认-1,表示事务超时将依赖于底层事务系统; read-only:事务只读设置,默认为false,表示不是只读; rollback-for:须要触发回滚的异常定义,可定义多个,以“,”分割,默认任何RuntimeException都将致使事务回滚,而任何Checked Exception将不致使事务回滚; no-rollback-for:不被触发进行回滚的 Exception(s);可定义多个,以“,”分割; --> <tx:advice id="advice" transaction-manager="transactionManager"> <tx:attributes> <!-- 拦截save开头的方法,事务传播行为为:REQUIRED:必需要有事务, 若是没有就在上下文建立一个 --> <tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED" timeout="" read-only="false" no-rollback-for="" rollback-for=""/> <!-- 支持,若是有就有,没有就没有 --> <tx:method name="*" propagation="SUPPORTS"/> </tx:attributes></tx:advice> <!-- 定义切入点,expression为切人点表达式,以下是指定impl包下的全部方法,具体以自身实际要求自定义 --> <aop:config> <aop:pointcut expression="execution(* com.kaizhi.*.service.impl.*.*(..))" id="pointcut"/> <!--<aop:advisor>定义切入点,与通知,把tx与aop的配置关联,才是完整的声明事务配置 --> <aop:advisor advice-ref="advice" pointcut-ref="pointcut"/></aop:config>
能够用非容器依赖的编程方式进行几乎全部的测试工做,测试再也不是昂贵的操做,而是随手可作的事情。
编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。
编程式,比较灵活,可是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活。
编程式主要使用transactionTemplate。省略了部分的提交,回滚,一系列的事务对象定义,需注入事务管理对象
spring方便程序测试的实现代码:
1)基类,其实就是用来加载配置文件的@RunWith(SpringJUnit4ClassRunner.class) //使用junit4进行测试 @ContextConfiguration({"/spring/app*.xml","/spring/service/app*.xml"}) //加载配置文件 //------------若是加入如下代码,全部继承该类的测试类都会遵循该配置,也能够不加,在测试类的方法上 //控制事务,参见下一个实例 //这个很是关键,若是不加入这个注解配置,事务控制就会彻底失效! //@Transactional //这里的事务关联到配置文件中的事务控制器(transactionManager = "transactionManager"),同时 //指定自动回滚(defaultRollback = true)。这样作操做的数据才不会污染数据库!//@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) //------------ public class BaseJunit4Test { } 2)接着是咱们本身的测试类public class UserAssignServiceTest extends BaseJunit4Test{ @Resource //自动注入,默认按名称 private IBaseDao baseDao; @Test //标明是测试方法 @Transactional //标明此方法需使用事务 @Rollback(false) //标明使用完此方法后事务不回滚,true时为回滚 public void insert( ) { String sql="insert into user(name,password) values(?,?)"; Object[] objs=new Object[{"00","000"}; baseDao.insert( sql , objs ); String sql1="select * from user where name=? and password=? "; List<Map<String,Object>> list=baseDao.queryForList( sql1 , objs ); System.out.println(list); assertTrue(list.size( )>0); } }
-END-