(转)Spring简介
http://blog.csdn.net/yerenyuan_pku/article/details/52830571
阿昀以一个初学者的身份学习Spring框架,并按照一个小白的思路详细总结学习过程中的知识点,整理成一个系列,供后来人借鉴。
Spring是什么
Spring是一个开源的控制反转(Inversion of Control,IoC)和面向切面(AOP)的容器框架,它的主要目得是简化企业开发。
控制反转(IOC)
大概以前,业务逻辑层的代码很有可能这样写:
public class PersonServiceBean {
private PersonDao personDao = new PersonDaoBean();
public void save(Person person){
personDao.save(person);
}
}
从上可看出PersonDaoBean是在应用内部创建及维护的。所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。
依赖注入(Dependency Injection)
当我们把依赖对象交给外部容器负责创建,那么PersonServiceBean类可以改成如下:
public class PersonServiceBean {
private PersonDao personDao ;
// 通过构造器参数,让容器把创建好的依赖对象注入进PersonServiceBean,当然也可以使用setter方法进行注入。
public PersonServiceBean(PersonDao personDao){
this.personDao=personDao;
}
public void save(Person person){
personDao.save(person);
}
}
所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。
为何要使用Spring
至少在我看来,在项目中引入Spring立即可以带来下面的好处:
- 降低组件之间的耦合度,实现软件各层之间的解耦。
- 可以使用容器提供的众多服务,如:事务管理服务、消息服务等等。当我们使用容器管理事务时,开发人员就不再需要手工控制事务,也不需处理复杂的事务传播。
- 容器提供单例模式支持,开发人员不再需要自己编写实现代码。
- 容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。
- 容器提供的众多辅作类,使用这些类能够加快应用的开发,如: JdbcTemplate、HibernateTemplate。
- Spring对于主流的应用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,这样更便于应用的开发。
使用Spring的好处
上面我们就已详细列出了使用Spring框架带来的好处,我们仅就第二点进行详细说明之。
当使用Spring框架时,我们可以使用容器提供的众多服务。
试想若要是不使用Spring框架,那么使用Hibernate框架进行事务操作就应是:
Hibernate的事务操作:
public void save(){
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Info info = new Info("Spring框架");
info.setContent("阿昀手把手教你学习Spring框架");
session.save(info);
session.getTransaction().commit();
}
既不使用Spring框架,也不使用Hibernate框架,直接使用最原始的JDBC技术进行事务操作,代码就应是:
JDBC的事务操作:
Connection conn = null;
try {
......
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
stmt.executeUpdate("update person where name='叶天'");
conn.commit();
......
} catch (Exception e) {
conn.rollback();
} finally {
conn.close();
}
而如果使用Spring框架,那我们就不再需要手工控制事务了。另外,如果使用Spring框架,我们也不需要处理复杂的事务传播行为了。我们举例子来说明之。
例如,有代码:
public void payment(){
Bean1.update(); // 更新金额
Bean2.save(); // 记录操作日志
}
public class Bean1 {
public void update(){ // 注意:下面省略了一些代码
Connection conn = null;
conn.setAutoCommit(false);
Statement.executeUpdate("update account set amount=? where id=?");
}
}
public class Bean2 {
public void save(){ // 注意:下面省略了一些代码
Connection conn = null;
conn.setAutoCommit(false);
Statement.executeUpdate("insert into Log (content) values (?)");
}
}
如果我们不使用Spring框架,针对下面这两种业务需求,我们该如何做呢?
- 第1种可能的业务需求:要求Bean1.update()和Bean2.save()在同一个事务中执行。
- 第2种可能的业务需求:要求不管Bean1.update()的事务是否成功,都需要记录操作日志。
若要是不使用Spring框架,针对第1种可能的业务需求,我们的解决办法用代码来表示就是:
public void payment(){
Connection conn = null;
conn.setAutoCommit(false);
Bean1.update(conn); // 更新金额
Bean2.save(conn); // 记录操作日志
// ...提交或回滚事务
}
public class Bean1 {
public void update(Connection conn){ // 注意:下面省略了一些代码
Statement.executeUpdate("update account set amount=? where id=?");
}
}
public class Bean2 {
public void save(Connection conn){ // 注意:下面省略了一些代码
Statement.executeUpdate("insert into Log (content) values (?)");
}
}
针对第2种可能的业务需求,我们不需要修改代码就可完成,因为Bean1.update()开启了一个事务,Bean2.save()同样也开启了一个事务,Bean1.update()开启的事务的回滚不会影响到Bean2.save()开启的事务。
倘若使用Spring框架,我们只需要通过声明式的事务属性配置就可以轻松地实现这两种业务需求。
要求Bean1.update()和Bean2.save()在同一个事务中执行。我们只须将代码改为:
@Transactional(propagation=Propagation.Required)
public void payment(){
Bean1.update(); // 更新金额
Bean2.save(); // 记录日志
}public class Bean1 {
@Transactional(propagation=Propagation.Required)
public void update(){
executeUpdate("update account set amount=? where id=?");
}
}public class Bean2 {
@Transactional(propagation=Propagation.Required)
public void save(){
executeUpdate("insert into Log (content) values (?)");
}
}要求不管Bean1.update()的事务是否成功,都需要记录日志。我们只须将代码改为:
@Transactional(propagation=Propagation.Required)
public void payment(){
Bean1.update(); // 更新金额
Bean2.save(); // 记录日志
}public class Bean1 {
@Transactional(propagation=Propagation.Required)
public void update(){
executeUpdate("update account set amount=? where id=?");
}
}public class Bean2 {
@Transactional(propagation=Propagation.RequiresNew)
public void save(){
executeUpdate("insert into Log (content) values (?)");
}
}
轻量级与重量级概念的划分
经常会有人问到Spring是属于轻量级框架,还是属于重量级框架呢?其实划分一个应用是否属于轻量级还是重量级,主要看它使用了多少服务。使用的服务越多,容器要为普通java对象做的工作就越多,必然会影响到应用的发布时间或者是运行性能。
对于Spring容器来说,它提供了很多服务,但这些服务并不是默认为应用打开的,应用需要某种服务,还需要指明使用该服务,如果应用使用的服务很少,如:只使用了Spring核心服务,那么我们可以认为此时应用属于轻量级的,如果应用使用了Spring提供的大部分服务,这时应用就属于重量级的。目前EJB容器就因为它默认为应用提供了EJB规范中所有的功能,所以它属于重量级。
(转)Spring简介的更多相关文章
- Spring学习系列(一) Spring简介
Spring简介 之前一直想写点东西,可一直没有开始实施,各种原因都有,最大原因可能还是自己太懒了,嘿嘿.最近在看Spring in action这本书,为了能让自己坚持下去把书看完,这次决定同步的在 ...
- [原创]java WEB学习笔记96:Spring学习---Spring简介及HelloWord
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Spring简介和基础
Spring介绍 1.什么事Spring? spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架. spring的设计模式是单例模式和工厂模式. 2.spring的四大优点 轻量 ...
- 【Spring 1】Spring简介
一.Spring简介 首先,Spring框架是由于软件开发的复杂性而创建的.Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情.然而,Spring的用途不仅仅限于服务器端的开 ...
- Spring框架入门之Spring简介
一.Spring简介(由Rod Johnson创建的一个开源框架) Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿 ...
- spring框架篇(一)-------spring简介与配置文件使用控制反转事例
spring简介 Spring 是一个开源框架,中文意思就是春天,也许是作者想让自己的这个框架给Java开发人员带来春天吧.其官方网站是 https://spring.io/ ,可以在官方网站下载到完 ...
- Spring使用笔记(一)Spring简介
Spring简介 Spring丰富的功能的底层都依赖于它的两个核心特性: 1.依赖注入(dependency injection, DI): 每个对象负责管理与自己协作的对象(即它所依赖的对象)的引用 ...
- Unit01: Spring简介 、 Spring容器 、 Spring IOC
Unit01: Spring简介 . Spring容器 . Spring IOC Spring (1)Spring是什么? Spring是一个开源的用来简化应用开发的框架. (2)Spring的特点? ...
- spring简介及常用术语
1.引入 在开发应用时常会遇到如下问题: 1)代码耦合性高: 2)对象之间依赖关系处理繁琐: 3)事务控制繁琐: 2.Spring简介 1)Spring概述 什么是Spring: ①Spring是一个 ...
- Spring(一)--Spring简介
Spring简介 1. Spring的特点 Spring (春天,绿色) 容器 01.Java EE开发者的春天,大大简化了代码量 02.使用IOC来降低主业务之间的耦合度 03.使用AOP来降低主 ...
随机推荐
- bzoj5063
平衡树 6个操作做完当然GG了,其实只有两个操作,翻转[A+1,A+B],把这个区间放到C的后面,那么就是基本splay操作了,可是好久没打,又GG了,splay函数写错了... #include&l ...
- In-App Purchase Programming Guide----(七) ----Restoring Purchased Products
Restoring Purchased Products Users restore transactions to maintain access to content they’ve alread ...
- CodeForces 718A Efim and Strange Grade (贪心)
题意:给定一个浮点数,让你在时间 t 内,变成一个最大的数,操作只有把某个小数位进行四舍五入,每秒可进行一次. 析:贪心策略就是从小数点开始找第一个大于等于5的,然后进行四舍五入,完成后再看看是不是还 ...
- 斯坦福CS231n—深度学习与计算机视觉----学习笔记 课时11
课时11 神经网络训练细节part1(下) 2010年,Glorot等人写的论文,我们称之为Xavier初始化,他们关注了神经元的方差表达式.他们推荐一种初始化方式,那就是对每个神经元的输入进行开根号 ...
- E20180404-ts
aero adj. 航空的,飞行的,飞机的; wheel n. 轮子; 旋转; Wheels 汽车; 有…轮子的汽车(或自行车等); vi. 转动,旋转; 突然转变方向; foil n. 箔,金 ...
- E20180331-hm
corresponding adj. 相当的,对应的; 通信的; 符合的,符合; 一致的; implicitly adv. 含蓄地; 暗示地; 无疑问地; 无保留地; causal adj. 具有因 ...
- 51nod1126【矩阵快速幂】
思路: 自己的一点心得:中间矩阵为最终矩阵. 搞出来很简单的: #include <bits/stdc++.h> using namespace std; const int N=1e2+ ...
- poj3249【拓扑排序】
//题意: 给出一个有向无环图,每个顶点都有一个权值. // 求一条从入度为0的顶点到出度为0的顶点的一条路径, // 路径上所有顶点权值和最大. //我觉得只要明 ...
- iOS 设置UITextView的Placeholder
代码如下: - (void)setupTextView { UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, ...
- python之请求报文对比(假定最多二维字典)
两段请求报文,判断不一样的key和value,只判断d2里和d1不同的值,和全部不同的key ok_req={ "version": "9.0.0", &quo ...