Spring基础
介绍
多模块集合,Spring Framework
- 简化开发,解耦,集成其他框架
- 低侵入式设计
- aop与di
- 支持声明式事务
Spring模块
- Spring Core:基础,主要提供IOC依赖注入功能
- Spring AOP :提供了面向切面的编程实现。
- Spring JDBC : Java数据库连接。
- Spring JMS :Java消息服务。
- Spring ORM : 用于支持Hibernate等ORM工具。
- Spring Web : 为创建Web应用程序提供支持。
- Spring Test : 提供了对 JUnit 和 TestNG 测试的支持。
@RestController 与 @Controller
- @Controller不加@ResponseBody属于传统的Spring MVC应用,返回的是一个试图 @Controller加@ResponseBody返回JSON或XML形式数据,相当于@Controller+@ResponseBody=RestController
@ResponseBody注解是将Controller方法反悔的对象转为指定的格式后,写入HTTP对象的body中,一般返回Json
- @RestController返回Json或XML数据 @RestController值返回对象,对象以Json或XML形式写入HTTP响应中,属于RESTful Web服务
IOC与AOP
IOC
是一种设计思想,将原本程序中手动创建对象的控制权,交由Spring框架管理。IOC实际上是一个MAP(key,value),Map存放的是各种对象。
对象之间的相互依赖关系交给IOC容器管理,并由IOC容器完成对象的注入。IOC像是一个工厂,当我们需要一个对象,只需要配置好配置文件/注解,不用考虑是什么时候被创建出来的。
初始化过程
- XML读取
- resource解析
- BeanDefinition注册
- BeanFactory(它负责生产和管理各个 bean 实例)
AOP
面向切面编程,能够将与业务无关,却为业务模块共同调用的逻辑或责任,比如日志,事务等封装起来,减少系统的重复代码,降低模块之间的耦合度,有利于未来的扩展性。
基于动态代理
- JDK:如果要代理的对象,实现了某个街口,就会使用JDK创建代理对象,通过反射
- Cglib:没有实现接口的对象,使用Cglib生成一个被代理对象的子类作为代理
Spring bean
bean的作用域
- singleton:唯一bean实例,Spring bean默认都是单例的
- prototype:每次请求都会生一个新的bean实例
- request : 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
- session : 每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效。
- global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义
Spring中的单例bean的线程安全问题
单例bean的存在主要是因为多线程操作同一个对象的时候,对这个对象非静态成员变量的写操作会存在线程安全问题。
解决方式:在类中定一个ThreadLocal成员变量,将需要可变的成员变量保存在ThreadLocal中
@Component与@Bean区别
- 作用对象不同,@Component注解作用于类,@Bean作用于方法;
- @Component通过类路径扫描来自动装配到Spring容器中,@Bean通常是我们在标有该注解的方法中定义产生这个bean;
- @Bean注解自定义更强,当引用第三方库类需要装配Spring容器,只能使用@Bean
将一个类声明为Spring的bean注解有哪些?
一般使用@Autowired自动装配bean,要想把类标识成可用于 @Autowired 注解自动装配的 bean 的类,可以用以下方式
- @Component :通用的注解,可标注任意类为 Spring 组件。如果一个Bean不知道属于哪个层,可以使用@Component 注解标注。
- @Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。
- @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao层。
- @Controller : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。
Spring中的bean生命周期(重点)
对象实例化->属性注入->初始化->销毁
- 解析类得到BeanDefinition
- 有多个构造方法,推断构造方法
- 确定好构造方法,进行实例化得到对象
- 对对象中加了@Autowired注解的属性进行属性填充
- 回调Aware方法,比如BeanNameAware、BeanFactroyAware
- 调用BeanPostProcessor的初始化前的方法
- 调用初始化方法
- 调用BeanPostProcessor的初始化后的方法,这里会进行AOP
- 如果当前创建的bean是单例的则会把bean放入单例池
- 使用bean
- Spring容器关闭调用DisposableBean中的destroy()方法
Spring mvc
MVC是一种设计模式,Spring MVC是一个优秀的MVC框架
工作原理
- 用户发起一个请求达到前端控制器DispatcherServlet,接受用户请求与响应
- DispatcherServlet根据请求信息调用HandlerMapping,解析对应的请求Handler
- 解析到对应的Handler(相当于Controller)后,开始由HandlerAdapter适配器处理
- HandlerAdapter会根据Handler来调用真正的处理器处理请求,并处理相应的业务逻辑
- 处理器处理完后,返回一个ModelAndView对象,Model是返回的数据对象,View是一个逻辑的View
- 视图解析器会根据逻辑View查找给实际的View
- DispatcherServlet把返回的Mode传给View(视图宣传)
- 把View返回给请求者
Spring用到的设计模式
- 工厂模式:Spring使用工厂模式通过BeanFactory、ApplicationContext创建bean的对象
- 代理模式:AOP功能的实现
- 单例模式:Spring中的Bean默认都是单例的
- 模版模式:Spring中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式
- 适配器模式:spring MVC 中也是用到了适配器模式适配Controller
Spring事务
Spring管理事务的方式
- 编程式事务,硬编码
- 声明式事务,配置文件
声明式事务
- 基于XML的声明式事务
- 基于注解的声明式事务
Spring事务的隔离级别
有5个表示隔离级别的常量
- TransactionDefinition.ISOLATION_DEFAULT:数据库默认的隔离界别,Mysql 默认采用的 REPEATABLE_READ(可重复读)隔离级别 Oracle 默认采用的 READ_COMMITTED(已提交读)隔离级别
- TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
- TransactionDefinition.ISOLATION_READ_COMMITTED: 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
- TransactionDefinition.ISOLATION_REPEATABLE_READ: 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
- TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
Spring事务传播行为
支持当前事务
- TransactionDefinition.PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
- TransactionDefinition.PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
- TransactionDefinition.PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)
不支持当前事务
- TransactionDefinition.PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。
- TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
- TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。
其他
- TransactionDefinition.PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED
@Transaction
@Transaction作用于类上时,该类所有public方法都具有该类型的事务属性,也可以在方法级别使用该标记覆盖类级别的定义。如果类或者方法加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚。
在@Transactional注解中如果不配置rollbackFor属性,那么事物只会在遇到RuntimeException的时候才会回滚,加上rollbackFor=Exception.class
,可以让事物在遇到非运行时异常时也回滚。
Enjoy Reading This Article?
Here are some more articles you might like to read next: