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框架,我们只需要通过声明式的事务属性配置就可以轻松地实现这两种业务需求。

  1. 要求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 (?)");
    }
    }
  2. 要求不管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简介的更多相关文章

  1. Spring学习系列(一) Spring简介

    Spring简介 之前一直想写点东西,可一直没有开始实施,各种原因都有,最大原因可能还是自己太懒了,嘿嘿.最近在看Spring in action这本书,为了能让自己坚持下去把书看完,这次决定同步的在 ...

  2. [原创]java WEB学习笔记96:Spring学习---Spring简介及HelloWord

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. Spring简介和基础

    Spring介绍 1.什么事Spring? spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架. spring的设计模式是单例模式和工厂模式. 2.spring的四大优点 轻量 ...

  4. 【Spring 1】Spring简介

    一.Spring简介 首先,Spring框架是由于软件开发的复杂性而创建的.Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情.然而,Spring的用途不仅仅限于服务器端的开 ...

  5. Spring框架入门之Spring简介

    一.Spring简介(由Rod Johnson创建的一个开源框架)        Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿 ...

  6. spring框架篇(一)-------spring简介与配置文件使用控制反转事例

    spring简介 Spring 是一个开源框架,中文意思就是春天,也许是作者想让自己的这个框架给Java开发人员带来春天吧.其官方网站是 https://spring.io/ ,可以在官方网站下载到完 ...

  7. Spring使用笔记(一)Spring简介

    Spring简介 Spring丰富的功能的底层都依赖于它的两个核心特性: 1.依赖注入(dependency injection, DI): 每个对象负责管理与自己协作的对象(即它所依赖的对象)的引用 ...

  8. Unit01: Spring简介 、 Spring容器 、 Spring IOC

    Unit01: Spring简介 . Spring容器 . Spring IOC Spring (1)Spring是什么? Spring是一个开源的用来简化应用开发的框架. (2)Spring的特点? ...

  9. spring简介及常用术语

    1.引入 在开发应用时常会遇到如下问题: 1)代码耦合性高: 2)对象之间依赖关系处理繁琐: 3)事务控制繁琐: 2.Spring简介 1)Spring概述 什么是Spring: ①Spring是一个 ...

  10. Spring(一)--Spring简介

    Spring简介 1. Spring的特点 Spring (春天,绿色)  容器 01.Java EE开发者的春天,大大简化了代码量 02.使用IOC来降低主业务之间的耦合度 03.使用AOP来降低主 ...

随机推荐

  1. Java输入/输出(I/O)流的分类总结

    java.io中有四个重要的抽象类: InputStream(字节输入流) Reader(字符输入流) OutputStream(字节输出流) Writer(字符输出流) 其中,InputStream ...

  2. Transformations

    链接 分析:根据操作模拟 /* ID:wanghan PROB:transform LANG:C++ */ #include "iostream" #include "c ...

  3. 【Educational Codeforces Round 38 (Rated for Div. 2)】 Problem A-D 题解

    [比赛链接] 点击打开链接 [题解] Problem A Word Correction[字符串] 不用多说了吧,字符串的基本操作 Problem B  Run for your prize[贪心] ...

  4. 廖雪峰python3练习题三

    条件判断 题目: 答案: #!/usr/bin/env python3 #-*- coding:utf-8 -*- heigth = 1.75 weigth = 80.5 bim = weigth / ...

  5. JDK7中匿名内部类中使用局部变量要加final,JDK8中不需要,但jdk会默认加上final

    今天看书的时候看到了局部内部类,书上说局部内部类可以访问局部变量,但是必须是final的.因为局部变量在方法调用之后就消失了,使用final声明的话该局部变量会存入堆中,和内部类有一样的声明周期.但是 ...

  6. 斯坦福CS231n—深度学习与计算机视觉----学习笔记 课时11

    课时11 神经网络训练细节part1(下) 2010年,Glorot等人写的论文,我们称之为Xavier初始化,他们关注了神经元的方差表达式.他们推荐一种初始化方式,那就是对每个神经元的输入进行开根号 ...

  7. hdoj1575【矩阵快速幂】

    题意:非常清晰! 直接搞吧. #include <iostream> #include <stdio.h> #include <string.h> #include ...

  8. PTA 2-1 列出连通集【DFS+BFS基础】

    给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点. 输入格式: 输入第1 ...

  9. poj 3415 Common Substrings【SA+单调栈】

    把两个串中间加一个未出现字符接起来,然后求SA 然后把贡献统计分为两部分,在排序后的后缀里,属于串2的后缀和排在他前面属于串1的后缀的贡献和属于串1的后缀和排在他前面属于串2的后缀的贡献 两部分分别作 ...

  10. CF788B Weird journey

    总共有n个节点,m条路径,要求其中m-2条路径走两遍,剩下2条路径仅走一遍,问不同的路径总数有多少,如果仅走一遍的两条边不同则将这两条路径视为不同. 可以把每条边都拆成两条重边,每条边的度数都是偶数了 ...