Spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的容器框架,使用基本的JavaBean代替EJB(企业Java Beans),并提供了很多的企业应用功能,解决了企业应用开发的复杂性。
主要优点:
Spring可以将简单的组件配置、组合称为复杂的应用。在Spring中,应用对象被声明式地组合,典型的是在一个xml文件里。spring还提供了很多基础功能,事务管理、持久化框架集成、MVCJNDI、JDBC层抽象。
面向切面编程,可以说是oop的补充与完善。oop引入封装、继承、多态的概念建立一个对象层次结构,用来模拟公告行为的一个集合。当我们需要为分散的对象引入公告行为时,oop就有点力不从心。oop适合从上到下的关系,不适合从左到右的关系。如日志功能,日志通常水平散布在所有对象层次中,而且与其对象的核心功能无关。类似的还有安全性、异常处理等。这种散布在各处无关的代码称为横切代码。
AOP技术将那些影响多个类的公告行为封装到一个可重用模块,并命名为aspect。简单来说,aspect就是将那些与业务无关,却被业务模块共用的代码封装起来,减少系统重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
AOP将软件系统分为两个部分:核心关注点和横切关注点。业务主要负责处理核心关注点,而横切关注点,如权限认证、事务、日志,经常发生在核心关注点多处,且基本相似。AOP的作用就是分离核心关注点和横切关注点。
Inversion of Controller,控制反转。
对于面向对象设计及编程的基本思想,简单来说就是把复杂系统分解成相互合作的对象,这些对象进行封装后,内部实现对外部是透明的,从而降低解决问题的复杂度,而且可以灵活的被重用和扩展。
IOC理论提出的观点:借助于第三方实现具有依赖关系的对象之间的解耦。
由于第三方的关系,也就是IOC,A、B、C、D四个对象没有了耦合关系,全部对象的控制权都交给了第三方,IOC也就成了整个系统的关键核心,IOC也就类似粘合剂的作用。
在没有引入IOC容器之前,对象A依赖与对象B,如果A在初始化或运行到某一步时,就必须去主动创建对象B。而引入IOC之后,A和B就失去了联系,所以当A再需要B时,IOC容器会主动创建一个对象B注入A。
可以看出,对象A获得依赖对象B的过程由主动变成被动,控制权反转了。
Spring已经集成了20多个模块,主要分为:核心容器、数据访问/集成、web、AOP、工具、消息和测试
2.Spring Context
基于 bean,提供上下文信息,扩展出JNDI、EJB、电子邮件、国际化、校验和调度等功能。
3.Spring DAO
提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码,还提供了声明性事务管理方法。
4.Spring ORM
提供了常用的“对象/关系”映射APIs的集成层。 其中包括JPA、JDO、Hibernate、MyBatis 等。
5.Spring AOP
提供了符合AOP Alliance规范的面向方面的编程实现。
6.Spring Web
提供了基础的 Web 开发的上下文信息,可与其他 web 进行集成。
7.Spring Web MVC
提供了 Web 应用的 Model-View-Controller 全功能实现。
Spring通过依赖注入实现控制反转
Spring本身并不提供bean的线程安全策略,可以说Spring中的bean不具备线程安全的特性,但具体情况还要结合scope分析。
Spring 的 bean 作用域(scope)类型
1、singleton:单例,默认作用域。
2、prototype:原型,每次创建一个新对象。
3、request:请求,每次Http请求创建一个新对象,适用于WebApplicationContext环境下。
4、session:会话,同一个会话共享一个实例,不同会话使用不用的实例。
5、global-session:全局会话,所有会话共享一个实例。
线程安全问题,就要从单例和原型bean说明
原型bean不会有线程安全问题,单例如果是无状态bean,也不会有。
如果不指定Bean的作用域,Spring默认使用singleton作用域。Java在创建Java实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype作用域Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将Bean被设置成prototype作用域。
spring中bean装配有两种方式:
1.隐式的bean发现机制和自动装配
2.在java代码或者XML中进行显示配置
在xml进行显示配置,用bean标签;
在Java中进行显示配置,通过@Configuration@Bean;
隐式配置分为两步,组件扫描(ComponentScan)和自动装配(Autowired)
@ComponentScan作用是扫描带有@Component注解的类,并为其创建bean。默认是扫描同一包下的类,当然也可以加入参数,指定包名。
如@ComponentScan(basePackages={“com.zcs”})或者@ComponentScan(basePackageClasses={CDPlayer.class,DVDPlayer.class})(即这些类所在的包)
@Autowired满足自动依赖装配,可以作用在任何方法上面。
事务隔离级别指的是一个事务对数据的修改与另一个并行的事务的隔离程度,当多个事务同时访问相同数据时,如果没有采取必要的隔离机制,就可能发生以下问题
什么是事务:
事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败.
事务特性(4种):
原子性 (atomicity):强调事务的不可分割.
一致性 (consistency):事务的执行的前后数据的完整性保持一致.
隔离性 (isolation):一个事务执行的过程中,不应该受到其他事务的干扰
持久性(durability) :事务一旦结束,数据就持久到数据库
如果不考虑隔离性引发安全性问题:
脏读 :一个事务读到了另一个事务的未提交的数据
不可重复读 :一个事务读到了另一个事务已经提交的 update 的数据导致多次查询结果不一致.
虚幻读 :一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结果不一致.
解决读问题: 设置事务隔离级别(5种)
DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
未提交读(read uncommited) :脏读,不可重复读,虚读都有可能发生
已提交读 (read commited):避免脏读。但是不可重复读和虚读有可能发生
可重复读 (repeatable read) :避免脏读和不可重复读.但是虚读有可能发生.
串行化的 (serializable) :避免以上所有读问题.
Mysql 默认:可重复读
Oracle 默认:读已提交
用户向服务器发送请求,请求被Spring前端控制器ServletDispatcherServlet捕获;
DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter;(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法)
提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
ViewResolver 结合Model和View,来渲染视图;将渲染结果返回给客户端。
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径