Spring之初体验

  • Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和AOP(Aspect Oriented Programming 面向切面编程)为内核,使用基本的JavaBean来完成以前只能有EJB完成的工作(现在这句话好像就是废话,以后我们会慢慢来说明)。

在实际开发当中,通常服务器端采用三层体系架构,分别为表示层(web)、业务逻辑层(service)、持久层(DAO)。Spring对每一层都提供了技术支持,在表示层提供了与Structs2框架的整合,在业务逻辑层可以管理事物,记录日志等,在持久层可以整合Hibernate、JDBCTemplate等技术,从设计上来看,给予了Java程序员很多自由,为商业开发提供了良好的解决方案。

Spring框架的优点

Spring具有简单、可测试和松耦合的特点,从这个角度出发,Spring不仅可以用于服务器端开发,而且可以应用于任何Java应用的开发中。其优点总结如下:

方便解耦、简化开发:Spring就是一个工厂,可以将所有对象创建和依赖关系维护交给Spring管理;

AOP编程的支持:Spring提供面向切面编程,可以方便的实现对程序进行权限管理、运行监控等功能;

声明式事物的支持:只需要通过配置就可以完成对事物的管理,无需手动编程;

方便程序的测试:Spring对JUnit4支持,可以通过注解方便地测试Spring程序;

方便集成各种优秀框架:Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(Struts2、Hibernate、MyBatis、Quartz等)的直接支持;

降低JavaEE API的使用难度:Spring对JavaEE开发中难以使用的一些API(JDBC、JavaMail、远程调用)都提供了封装,使API应用难度降低。

Spring体系结构

Spring框架采用分层架构,其体系结构图如下,我们着重介绍一下Core Container、Data Access/Intergration、Web、AOP(Aspect Oriented Programming)部分。

  • Core Container(核心容器)

Spring的核心容器是建立在其他模块的基础上的,由Beans模块、Core核心模块、Context上下文模块和Expression Language表达式语言模块组成。

Beans模块:提供BeanFactory,是工厂模式的经典实现,Spring将管理对象成为Bean;

Core核心模块:Spring的核心类库,提供了Spring框架的基本组成部分,包括IoC和DI功能;

Context上下文模块:建立在Core和Beans基础上,访问定义和配置任何对象的媒介,ApplicationContext接口就是上下文模块的焦点;

Expression Language模块:运行时查询和操作对象图的强大表达式语言。

  • Data Access/Intergration(数据访问/集成)

JDBC模块:提供一个JDBC(Java Data Base Connectivity)的抽象层,大幅度减少了在开发过程中对数据库操作的代码;

ORM模块:提供对常用ORM框架的管理和辅助支持,Spring本身不对ORM进行实现,仅是对常见ORM框架的封装;

OXM模块:提供了一个支持对象/XML映射实现对JAXB、Castor使用XMLBeans、JiBX和XStream的抽象层

Transactions事物模块:支持编程和声明式事务管理实现特殊接口类,并且对所有的POJO都适用。

  • Web模块

Spring的Web层包括web、Servlet、Struts和Portlet组件,具体介绍如下:

Web 模块提供了基本的面向 web 的集成特性,如多个文件上传的功能和使用 servlet 监听器的IOC容器初始化以及面向 web 应用程序的上下文;

Servlet模块:包括Spring模型-视图-控制器(MVC)实现web应用程序;

Struts模块:包含支持类内的Spring应用程序,集成经典的Struts web层;

Portlet模块:提供了在portlet环境中使用MVC实现,类似Web-Servlet模块的功能。

第一个Spring程序
  • 当然啦,首先是下载Spring框架包,本文中使用的是4.3.4的版本,下载地址为:http://repo.spring.io/release/org/springframework/spring/4.3.4.RELEASE/,选择spring-framework-4.3.4.RELEASE-dist.zip下载。
  • 然后在Eclipse中创建web项目,并将Spring所需要的jar包复制到项目的lib目录中,并且对包构建路径,jar包为Spring的4个基础包:

spring-core-4.3.4.RELEASE.jar:包含Spring框架基本的核心工具类,Spring其他组件都要用到这个包中的类;

spring-beans-4.3.4.RELEASE.jar:包含访问配置文件、创建和管理bean以及进行IoC或者DI操作相关的类;

spring-context-4.3.4.RELEASE.jar:Spring提供在IoC功能上的扩展服务,此外还提供企业级的服务,如邮件服务、任务调度、JNDI定位、缓存以及各种视图层框架的封装等;

spring-expression-4.3.4.RELEASE.jar:定义了spring的表达式语言。

其中还有一个记录日志的jar文件:文件下载路径为:http://commons.apache.org/proper/commons-logging/download_logging.cgi

项目的目录结构如下:

整个项目包的导入工作已经完成,随后是创建UserDao接口和UserDaoImpl实现类:

  1. public interface UserDao {
  2. public void sayHello();
  3. }
  4.  
  5. public class UserDaoImpl implements UserDao{
  6.  
  7. @Override
  8. public void sayHello() {
  9. // TODO Auto-generated method stub
  10. System.out.println("spring: hello user dao");
  11. }
  12.  
  13. }

  然后在src目录下创建applicationContext.xml文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
  3. "http://www.springframework.org/dtd/spring-beans.dtd">
  4. <beans>
  5. <!-- 将指定对象配置给spring,让spring创建其实例 -->
  6. <bean id="userDao" class="com.ioc.UserDaoImpl"></bean>
  7. </beans>

  最后是创建主类Client,实现对方法的调用:

  1. public class Client {
  2.  
  3. public static void main(String[] args) {
  4. // TODO Auto-generated method stub
  5. //定义配置文件路径
  6. String xmlPath = "applicationContext.xml";
  7. //初始化spring容器,加载配置文件
  8. ApplicationContext application = new ClassPathXmlApplicationContext(xmlPath);
  9. //通过容器获取UserDao实例
  10. UserDao userDao = (UserDao) application.getBean("userDao");
  11. userDao.sayHello();
  12. }
  13.  
  14. }

  最后整个项目的目录结构图如下:

  运行该主函数就会在控制台中看到输出信息:“spring: hello user dao”。如上即为一个spring简单IoC的实例,实例不是有调用者来创建的,而是由Spring容器创建,Spring容器会控制程序之间的关系,而不是由程序代码直接控制,这样控制权由应用代码转移到了外部容器,控制权发生了反转,也就是IoC的思想。

  接下来我们再来看一看DI(依赖注入),它与控制反转的含义相同,只不过从不同的角度描述同一个概念。如果A类需要使用B类的对象才能实现某个功能,这时可以说A类对象依赖B类对象,而Spring容器在创建A类对象时,会自动将A类对象需要的B类对象注入到A类对象中,此过程就是依赖注入。Spring支持两种依赖注入:setter方法注入、构造方法注入。

属性setter注入:指IoC容器使用setter方法注入被依赖实例,通过调用无参构造器或无参static工厂方法实例化Bean后,调用该Bean的setter方法,即可实现基于setter的DI

构造方法注入:指IoC容器使用构造方法来注入被依赖的实例,基于构造器的DI通过调用带参数的构造方法来实现,每个参数代表一个依赖。

  我们通过setter注入的方式来说明DI,首先创建UserDaoImpl的两个依赖类BeforeAction和AfterAction,这两个类集成自Action接口,然后在UserDaoImpl类中加入两个私有的类对象,并实现两个对象的setter方法。

如下是BeforeAction和AfterAction的实现代码:

  1. public interface Action {
  2. public void doSomething();
  3. }
  4.  
  5. public class BeforeAction implements Action{
  6.  
  7. @Override
  8. public void doSomething() {
  9. // TODO Auto-generated method stub
  10. System.out.println("this is a method in BeforeAction");
  11. }
  12.  
  13. }
  14.  
  15. public class AfterAction implements Action{
  16.  
  17. @Override
  18. public void doSomething() {
  19. // TODO Auto-generated method stub
  20. System.out.println("this is a method in AfterAction");
  21. }
  22.  
  23. }

  然后是UserDaoImpl代码的改变:

  1. public class UserDaoImpl implements UserDao{
  2. //UserDaoImpl依赖的两个对象
  3. private BeforeAction beforeAction;
  4. private AfterAction afterAction;
  5. //实现依赖对象的setter方法
  6. public void setBeforeAction(BeforeAction beforeAction) {
  7. this.beforeAction = beforeAction;
  8. }
  9. public void setAfterAction(AfterAction afterAction) {
  10. this.afterAction = afterAction;
  11. }
  12. @Override
  13. public void sayHello() {
  14. // TODO Auto-generated method stub
  15. this.beforeAction.doSomething();
  16. System.out.println("spring: hello user dao");
  17. this.afterAction.doSomething();
  18. }
  19.  
  20. }

  最后是修改applicationContext.xml文件,实现UserDaoImpl对BeforeAction和AfterAction类的依赖注入。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
  3. "http://www.springframework.org/dtd/spring-beans.dtd">
  4. <beans>
  5. <!-- 将指定对象配置给spring,让spring创建其实例 -->
  6. <bean id="beforeAction" class="com.action.BeforeAction"/>
  7. <bean id="afterAction" class="com.action.AfterAction"/>
  8. <bean id="userDao" class="com.ioc.UserDaoImpl">
  9. <property name="beforeAction" ref="beforeAction"/>
  10. <property name="afterAction" ref="afterAction"/>
  11. </bean>
  12. </beans>

  整个项目最新的目录结构如下:

  其中Client中的代码不变,从而通过setter的方法,实现了将两个Action对象加入到UserDaoImpl中。

思来想去还是想介绍一下构造器方法的注入,只是简单的说明一下吧,在setter依赖注入的实现的代码基础上,只对两个文件进行修改(UserDaoImpl和applicationContext.xml)。其中在UserDaoImpl中添加一个构造方法,其中参数为BeforeAction和AfterAction对象,UserDaoImpl中增加的代码如下:

  1. public UserDaoImpl(BeforeAction before, AfterAction after){
  2. this.beforeAction = before;
  3. this.afterAction = after;
  4. }

  applicationContext.xml文件内容如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
  3. "http://www.springframework.org/dtd/spring-beans.dtd">
  4. <beans>
  5. <!-- 将指定对象配置给spring,让spring创建其实例 -->
  6. <bean id="beforeAction" class="com.action.BeforeAction"/>
  7. <bean id="afterAction" class="com.action.AfterAction"/>
  8. <bean id="userDao" class="com.ioc.UserDaoImpl">
  9. <!-- 如下为setter方法的依赖注入 -->
  10. <!-- property name="beforeAction" ref="beforeAction"/ -->
  11. <!-- property name="afterAction" ref="afterAction"/ -->
  12. <!-- 如下是构造器方式的依赖注入 -->
  13. <constructor-arg index="0" ref="beforeAction" />
  14. <constructor-arg index="1" ref="afterAction" />
  15. </bean>
  16. </beans>

  本篇博客主要讲解了Spring的基本知识,首先介绍了Spring框架的优缺点,随后介绍了框架体系结构,然后通过两个Spring实例分别实现了Spring的IoC和DI,帮助读者对Spring的控制反转(IoC)和依赖注入(DI)有进一步的理解。

Spring之初体验的更多相关文章

  1. spring cloud 初体验

    spring cloud分为注册端.客户端以及消费端 初体验的理解就是: 注册端就是将之前所有的应用在这边进行注册,然后给每个应用都生成自己的标识,这些应用就是来自于客户端,消费端则通过调用注册端(有 ...

  2. Spring(三) Spring IOC 初体验

    Web IOC 容器初体验 我们还是从大家最熟悉的 DispatcherServlet 开始,我们最先想到的还是 DispatcherServlet 的 init() 方法.我们发现在 Dispath ...

  3. 第23章 Spring MVC初体验

    23.1 鸟瞰Spring MVC 粗略的介绍了SpringMVC的主要组成部分,SpringMVC作为一个Web层的框架,最大的作用是把我从繁重的web.xml文件编写中解救出来,再也不要不停的添加 ...

  4. Spring入门初体验

    Spring其实就是一个容器,让我们更方便的拿到想要的对象. 1.编写一个service // userService.java public interface userService { publ ...

  5. spring roo初体验

    1.下载spring-roo-2.0.0.M1,并执行如下命令,在/usr/local/bin下面建立一个roo的软连接   sudo ln -s /Users/pud/Documents/still ...

  6. spring mvc(2) spring mvc初体验

    前面讲到随着前端技术的发展,web的开发已经实现了前后分离,并且spring mvc经过多个版本的更新,使用上也变得不一样,并且提供了很多便捷的功能.但是为了便于理解,我们使用比较原始的方式搭建spr ...

  7. spring native 初体验实现 小米控制美的空调

    目前关于 spring native 分享的文章还比较少 写这篇文章的主要目前是分享一下自己写的一个 小米控制美的空调 的程序 集成 spring native 过程中碰到的一些问题和解决方法 先放地 ...

  8. 215.Spring Boot+Spring Security:初体验

    [视频&交流平台] SpringBoot视频:http://t.cn/R3QepWG Spring Cloud视频:http://t.cn/R3QeRZc SpringBoot Shiro视频 ...

  9. Spring JDBCTemplate连接SQL Server之初体验

    前言 在没有任何框架的帮助下我们操作数据库都是用jdbc,耗时耗力,那么有了Spring,我们则不用重复造轮子了,先来试试Spring JDBC增删改查,其中关键就是构造JdbcTemplate类. ...

随机推荐

  1. 【AR实验室】ARToolKit之概述篇

    0x00 - 前言 我从去年就开始对AR(Augmented Reality)技术比较关注,但是去年AR行业一直处于偶尔发声的状态,丝毫没有其"异姓同名"的兄弟VR(Virtual ...

  2. 【.net 深呼吸】限制执行代码的权限

    前面好几篇文章,老周都跟大伙伴们聊了跟应用程序域有关的话题,干脆咱们一聊到底吧,做学问就应该这样,有恒心. App Domain的创建新应用程序域的方法中,有一个特殊的重载: public stati ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(66)-MVC WebApi 用户验证 (2)

    系列目录 前言: 回顾上一节,我们利用webapi简单的登录并进行了同域访问与跨域访问来获得Token,您可以跳转到上一节下载代码来一起动手. 继续上一篇的文章,我们接下来演示利用拿到的Token来访 ...

  4. 从netty-example分析Netty组件

    分析netty从源码开始 准备工作: 1.下载源代码:https://github.com/netty/netty.git 我下载的版本为4.1 2. eclipse导入maven工程. netty提 ...

  5. CSS 3学习——边框

    在CSS 3中可以设置边框圆角.边框阴影和边框图像,分别通过border-radius.border-image和box-shadow属性设置. 边框圆角 border-radius属性是以下4个属性 ...

  6. 代码的坏味道(17)——夸夸其谈未来性(Speculative Generality)

    坏味道--夸夸其谈未来性(Speculative Generality) 特征 存在未被使用的类.函数.字段或参数. 问题原因 有时,代码仅仅为了支持未来的特性而产生,然而却一直未实现.结果,代码变得 ...

  7. ADO.NET一小记-select top 参数问题

    异常处理汇总-后端系列 http://www.cnblogs.com/dunitian/p/4523006.html 最近使用ADO.NET的时候,发现select top @count xxxx 不 ...

  8. [原创]java使用JDBC向MySQL数据库批次插入10W条数据测试效率

    使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(100000),如何提高效率呢?在JDBC编程接口中Statement 有两个方法特别值得注意:通过使用addBatch( ...

  9. JDBC Tutorials: Commit or Rollback transaction in finally block

    http://skeletoncoder.blogspot.com/2006/10/jdbc-tutorials-commit-or-rollback.html JDBC Tutorials: Com ...

  10. ABAP单元测试最佳实践

    本文包含了我在开发项目中经历过的实用的ABAP单元测试指导方针.我把它们安排成为问答的风格,欢迎任何人添加更多的Q&A's,以完成这个列表. 在我的项目中,只使用传统的ABAP report. ...