Spring
Spring主要的目的:简化企业开发
一、spring的体系结构
控制反转(IoC:Inversion of Control ) /依赖 注入(DI:Dependency Injection )
面向切面编程(AOP:Aspect Oriented Programming)
二、spring的核心容器
1、BeanFactory
BeanFactory是基础类型的IOC容器,它提供了完整的IOC服务支持,简单来说,BeanFactory就是一个管理Bean的工厂,它主要负责初始化各种Bean,并调用它们的生命周期方法
BeanFactory接口有多个实现类,最常见的是XmlBeanFactory
@Test
public void test2(){
//实例化BanFactory核心容器对象
BeanFactory beanFactory=new XmlBeanFactory(new FileSystemResource("G:\\IDEAWS\\pro-spring\\spring-01- helloworld\\src\\main\\resources\\beans.xml"));
HelloWorld hw=(HelloWorld) beanFactory.getBean("helloworld");
String msg=hw.sayHello("word");
logger.info(msg);
}
2、ApplicationContext
ApplicationContext是BeanFactory的子接口,ApplicationContext不仅包含了BeanFactory的所有功能,还添加了对国际化,资源访问,事件传播等方面的支持
ApplicationContext接口有两个常用的实现类,具体如下所示
a)、ClassPathXmlApplicationContext: 该类从类路径中寻找指定的XML配置文件
b)、FileSystemXmlApplicationContext:该类从指定的文件系统中寻找指定的XML配置文件
public void shouldAnswerWithTrue()
{
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Hello hello = (Hello) applicationContext.getBean("hello");
logger.info(hello.hi());
}
三、spring的IOC和DI概念的理解
IOC和DI是一回事,只是在不同的角度去诠释同一个问题
1、控制反转(IOC)
由代码来维护程序之间的关系,有了spring容器之后,程序之间的这种关系,控制权由应用程序转移到到了Spring容器,控制器权发生了反转,这就是spring的控制反转,称为IOC
2、DI(依赖注入)
所谓的依赖注入:在程序运行的过程中临时组装各组件(各组件之间要有合适的接口)
四、事务
1、@Transactional不起作用的解决办法
1)检查方法是不是public的
2)你的异常类型是不是unchecked异常
3)数据库引擎要支持事务,如果是mysql,注意表要使用支持事务的引擎,比如innodb,如果是myisam,事务是不起作用的。
4)是否开启了对注解的解析
2、Spring事务的详情
事务属性包含了5个方面,如图所示:
1).事务超时
为了使应用程序很好地运行,事务不能运行太长的时间。因为事务可能涉及对后端数据库的锁定,所以长时间的事务会不必要的占用数据库资源。事务超时就是事务的一个定时器,在特定时间内事务如果没有执行完毕,那么就会自动回滚,而不是一直等待其结束。
2).事务只读
事务的第二个特性是它是否为只读事务。如果事务只对后端的数据库进行该操作,数据库可以利用事务的只读特性来进行一些特定的优化。通过将事务设置为只读,你就可以给数据库一个机会,让它应用它认为合适的优化措施。
3).事务的回滚机制
事务的回滚规则定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚(这一行为与EJB的回滚行为是一致的)
但是你可以声明事务在遇到特定的检查型异常时像遇到运行期异常那样回滚。同样,你还可以声明事务遇到特定的异常不回滚,即使这些异常是运行期异常。
在Spring 的世界里面我们一般使用@Transactional 注解在对应方法上面声明为一个事务方法。但是在默认不写@Transactional(rollbackFor = Exception.class)默认回滚RuntimeException
4).事务的传播行为
当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行,事务的传播行为可以由传播属性指定。spring定义了7种类传播行为
a)REQUIRED传播行为
当accountService中的transferAccounts()方法被另外一个事务方法payment()调用时,它默认会在现有的事务内运行。这个默认的传播行为就是REQUIRED,因此在payment()方法的开始和终止边界内只有一个事务。这个事务只在payment()方法结束的时候被提交。
b)REQUIRES_NEW传播行为
表示该方法必须启动一个新事务,并在自己的事务内运行。如果有事务在运行,就应该挂起它
5)事务的隔离级别
-
读未提交:READ UNCOMMITTED
允许Transaction01读取Transaction02未提交的修改
-
读已提交:READ COMMITTED
要求Transaction01只能读取Transaction01已提交的修改
-
可重复读:REPEATABLE READ
确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其他事务对这个字段进行更新
-
串行化:SERIALIZABLE
确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其他事务对这个
表进行添加,更新,删除操作。可以避免任何并发问题,但性能十分低下
6) spring中指定事务隔离级别
- 注解:用@Transaction注解声明式地管理事务时可以在@Transaction的isolation属性中设置隔离级别
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Override
public Account findAccountByAccountno(String accountno) {
return this.accountMapper.findAccoutByAccountno(accountno);
}
-
XML
可以在<tx:method>元素中指定事务隔离级别isolation=“隔离级别”