谈起Spring的历史,那我们先了解一下Java中Spring的初衷及目标吧:
一、Spring的初衷:
1、J2EE开始应该更加简单。
2、使用接口而不是使用类,是更好的编程习惯。Spring将使用接口的复杂度几乎降低到了零。
3、为JavaBean提供了一个更好的应用配置框架。
4、更多地强调面向对象的设计,而不是现行的技术如J2EE。
5、尽量减少不必要的异常捕捉。
6、使应用程序更加容易测试。
二、Spring的基本组成:
1、最完善的轻量级核心框架。
2、通用的事务管理抽象层。
3、JDBC抽象层。
4、集成了Toplink, Hibernate, JDO, and iBATIS SQL Maps。
5、AOP功能。
6、灵活的MVC Web应用框架。
三、Spring的目标:
1、可以令人方便愉快的使用Spring。
2、应用程序代码并不依赖于Spring APIs。
3、Spring不和现有的解决方案竞争,而是致力于将它们融合在一起。
Spring的一个最大的目的就是使J2EE开发更加容易。同时,Spring之所以与Struts、Hibernate等单层框架不同,是因为Spring致力于提供一个以统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合揉和在一起建立一个连贯的体系。可以说Spring是一个提供了更完善开发环境的一个框架,可以为POJO(Plain Old Java Object)对象提供企业级的服务。
Spring的基本思想
Spring的目标是简化Java应用开发,那么它是通过什么方式来实现这一目标的呢?前面我们说过DI和AOP是Spring的核心功能,更准确地说,Spring通过为DI和AOP这两种编程技术提供支持,来让应用更方便的进行开发。此外,Spring提倡基于POJO(Plain Old Java Object)的编程模型,提供了针对企业开发且屏蔽重复代码的工具类。在开始正式进入代码编写之前,我们先了解Spring简化开发的几个基本思想。
DI
面向对象的程序通过一组对象之间相互通信来实现特定功能,这里的通信具体来说就是一个对象对另一个对象的方法调用或者属性访问。比如有一个BlogRespositry
类负责将博客内容存储到数据库,一个BlogController
负责解析前端的Web请求。BlogController
接受到新建博客的请求之后,需要调用BlogRespositry
的方法来保存博客内容。这里BlogRespositry
就是BlogController
的一个依赖,具体体现在BlogController
会包含一个BlogRespositry
类型的成员变量。
class BlogController {
private BlogRepository blogRepository;
public BlogController() {
this.blogRepository = new BlogRepository();
...
}
...
}
在上面的代码中,BlogRespositry
在构造函数中自己去创建BlogRepository
类的实例。而使用依赖注入技术,则BlogRespositry
的依赖(即BlogRepository
类)是由外部实例化之后注入给它的。依赖注入也称为控制反转(IoC,Inversion of Controll)。当创建一个对象时,它所依赖的对象由外部传递给它,而非自己去创建所依赖的对象(向例子中这样通过new
操作)。因此,也可以说在对象如何获取它的依赖对象这件事情上,控制权反转了。这便是控制反转和依赖注入这两个名字的由来了。
DI可以让对象之间的关系更加松耦合,而且会促使你使用面向接口编程,同时也让测试更加方便。如果现在对这个概念还不是太理解没关系,下一节中我们将基于代码实例来深入了解DI的工作原理。
AOP
面向切面编程(Aspect Oriented Programming,AOP)是一种关注点分离的技术,通俗的说就是有机地将各部分代码进行分离,各司其职,互不干扰。软件开发中经常提一个词,叫做“业务逻辑”或者“业务功能”,我们的代码主要就是实现某种特定的业务逻辑。但是我们往往不能专注于业务逻辑,比如我们写业务逻辑代码的同时,还要关注事务管理、缓存、日志等一系列通用功能,如果每个业务功能都要和这些通用功能混在一起,是一件非常低效和痛苦的事情。所以,为了将业务功能的关注点和通用化功能的关注点分离开来,就需要AOP技术了。通用功能的代码实现,对应的就是我们说的切面(Aspect)。
简而言之,AOP就是一种在开发时将业务相关代码和业务无关的通用功能代码有机分离,而运行时又能够整合到一起形成完整功能的一整套技术。Spring框架中一些模块本身就是基于AOP技术来实现的,例如事务处理和安全相关的模块。
基于POJO的编程模型
Java开发领域的一大特色就是有大量开源框架可供我们选择和使用。通常情况下,使用一种开发框架,我们编写的业务类都需要去继承框架提供的类或者接口,如此方能使用框架提供的基础功能。而对于Spring框架,只需POJO就能使用其强大的功能。Spring不强制我们依赖于其特定的API,这称之为“非侵入式”开发,能够让代码更加简单并且更容易复用。
POJO是Plain Old Java Object的缩写,是软件开发大师Martin Fowler提出的一个概念,指的是一个普通Java类。也就说,你随便编写一个Java类,就可以称之为POJO。之所以要提出这样一个专门的术语,是为了与基于重量级开发框架的代码相区分,比如EJB,我们编写的类一般都要求符合特定编码规范,实现特定接口、继承特定基类,而POJO则可以说是百无禁忌,灵活方便。
大家在学习过程中会经常遇到另外两个概念:JavaBeans和Spring Bean。这两者和POJO这个概念经常联系在一起,这里简单介绍一下。
-
JavaBeans是一种Java规范定义的一种组件模型,它包含了一些类编码的约定。简单来说,一个类如果拥有一个默认构造函数,由国有访问内部属性且符合命名规范的
setter
和getter
方法,同时实现了io.Serializable
接口,就是一个JavaBean。那么为什么要这些约定呢? 因为大家都遵守这些约定,在编写或者修改一个类的时候,就能很容易在可视化的开发环境中进行操作,也更方便地分发给他人。 -
Spring Bean是被Spring维护和管理的POJO。最早Spring只能管理符合JavaBeans规范的对象,这也是为什么称之为Spring Bean的原因。但是现在只要是POJO就能被Spring容器管理起来,而且这也是最为常见的情况。
模板代码
在开发过程中,很多的功能的实现,都会涉及到完全相同的代码,最典型的例子就是JDBC的使用。
public Employee getEmployeeById(long id) {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null; try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement("select id, name from employee where id=?");
stmt.setLong(1, id);
rs = stmt.executeQuery();
Employee employee = null;
if (rs.next()) {
employee = new Employee();
employee.setId(rs.getLong("id"));
employee.setName(rs.getString("name"));
} return employee;
} catch (SQLException e) {
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
}
}
}
return null;
}
而Spring通过Template这样一种设计模式来解决这样的问题。Template模式,就是把固定的逻辑放到一个模板类中,变化的部分放到自己实现的类中,通过继承或者回调的方式把固定逻辑和变化部分结合到一起。比如在面的代码中,数据库连接和数据库异常处理的大量代码都是一模一样的,不同的数据库访问操作只有数据查询部分的逻辑是不一样的。Spring将这些代码被放在了JdbcTemplate
这个模板类中,大大简化了数据访问的开发工作。
public Employee getEmployeeById(long id) {
return jdbcTemplate.queryForObject(
"select id, name from employee where id=?",
new RowMapper<Employee>() {
public Employee mapRow(ResultSet resultSet, int i) throws SQLException {
Employee employee = new Employee();
employee.setId(resultSet.getLong("id"));
employee.setName(resultSet.getString("name"));
return employee;
}
});
}
中软高科
微信号:javaedu
(长按上图,弹出“识别二维码”后可快速关注)
文章评论