《Spring实战》(第4版)

    

第一章:Spring之旅

    

1. 简化Java开发

为了降低Java开发的复杂性,Spring采取了以下4种关键策略:

  • 基于POJO的轻量级和最小侵入性编程;
  • 通过依赖注入和面向接口实现松耦合;
  • 基于切面和惯例进行声明式编程;
  • 通过切面和模板减少样板式代码。

1.1 激发POJO的潜能

  在基于Spring构建的应用中,它的类通常没有任何痕迹表明你使用了Spring。最坏的场景是,一个类或许会使用Spring注解,但它依旧是POJO。

  Spring赋予POJO魔力的方式之一就是通过DI来装配它们。

1.2 依赖注入(DI)

  耦合是必须的,但应当被小心谨慎地管理。

  创建应用组件之间协作的行为通常称为装配(wiring)。Spring有多种装配bean的方式,采用XML是很常见的一种装配方式。

        

                KnightMain.java加载包含Knight的Spring上下文

  这里的main() 方法基于knights.xml文件创建了Spring应用上下文。随后它调用该应用上下文获取一个ID为knight的bean。得到Knight 对象的引用后,只需简单调用embarkOnQuest() 方法就可以执行所赋予的探险任务了。注意这个类完全不知道我们的英雄骑士接受哪种探险任务,而且完全没有意识到这是由BraveKnight 来执行的。只有knights.xml文件知道哪个骑士执行哪种探险任务。

  Spring还支持使用Java来描述配置。

         

            Spring提供了基于Java的配置,可作为XML的替代方案

  通过DI,对象的依赖关系将由系统中负责协调各对象的第三方组件在创建对象的时候进行设定。对象无需自行创建或管理它们的依赖关系,如图所示,依赖关系将被自动注入到需要它们的对象当中去。

                    

          依赖注入会将所依赖的关系自动交给目标对象,而不是让对象自己去获取依赖 

1.3 应用切面

  DI能够让相互协作的软件组件保持松散耦合,而面向切面编程(aspect-oriented programming,AOP)允许你把遍布应用各处的功能分离出来形成可重用的组件。

  面向切面编程往往被定义为促使软件系统实现关注点的分离一项技术。系统由许多不同的组件组成,每一个组件各负责一块特定功能。除了实现自身核心的功能之外,这些组件还经常承担着额外的职责。诸如日志、事务管理和安全这样的系统服务经常融入到自身具有核心业务逻辑的组件中去,这些系统服务通常被称为横切关注点,因为它们会跨越系统的多个组件。

  • 实现系统关注点功能的代码将会重复出现在多个组件中。这意味着如果你要改变这些关注点的逻辑,必须修改各个模块中的相关实现。即使你把这些关注点抽象为一个独立的模块,其他模块只是调用它的方法,但方法的调用还是会重复出现在各个模块中。
  • 组件会因为那些与自身核心业务无关的代码而变得混乱。一个向地址簿增加地址条目的方法应该只关注如何添加地址,而不应该关注它是不是安全的或者是否需要支持事务。

            

        在整个系统内,关注点(例如日志和安全)的调用经常散布到各个模块中,而这些关注点并不是模块的核心业务

  AOP能够使这些服务模块化,并以声明的方式将它们应用到它们需要影响的组件中去。所造成的结果就是这些组件会具有更高的内聚性并且会更加关注自身的业务,完全不需要了解涉及系统服务所带来复杂性。总之,AOP能够确保POJO的简单性。

  如下图所示,我们可以把切面想象为覆盖在很多组件之上的一个外壳。应用是由那些实现各自业务功能的模块组成的。借助AOP,可以使用各种功能层去包裹核心业务层。这些层以声明的方式灵活地应用到系统中,你的核心应用甚至根本不知道它们的存在。这是一个非常强大的理念,可以将安全、事务和日志关注点与核心业务逻辑相分离。

            

            利用AOP,系统范围内的关注点覆盖在它们所影响组件之上

1.4 使用模板消除样板式代码

  因为使用Java API而导致的样板式代码,样板式代码的一个常见范例是使用JDBC访问数据库查询数据。在许多编程场景中往往都会导致类似的样板式代码,JMS、JNDI和使用REST服务通常也涉及大量的重复代码。

  Spring旨在通过模板封装来消除样板式代码。Spring的JdbcTemplate使得执行数据库操作时,避免传统的JDBC样板代码成为了可能。

          

2. 容纳你的Bean

在基于Spring的应用中,你的应用对象生存于Spring容器(container)中。Spring容器负责创建对象,装配它们,配置它们并管理它们的整个生命周期,从生存到死亡(在这里,可能就是newfinalize())

容器是Spring框架的核心。Spring容器使用DI管理构成应用的组件,它会创建相互协作的组件之间的关联。毫无疑问,这些对象更简单干净,更易于理解,更易于重用并且更易于进行单元测试。

Spring容器并不是只有一个。Spring自带了多个容器实现,可以归为两种不同的类型。bean工厂(由org.springframework.beans.factory.BeanFactory 接口定义)是最简单的容器,提供基本的DI支持。应用上下文(由org.springframework.context.ApplicationContext 接口定义)基于BeanFactory构建,并提供应用框架级别的服务,例如从属性文件解析文本信息以及发布应用事件给感兴趣的事件监听者。

2.1 使用应用上下文

Spring自带了多种类型的应用上下文。下面罗列的几个是你最有可能遇到的。

  • AnnotationConfigApplicationContext 从一个或多个基于Java的配置类中加载Spring应用上下文。
  • AnnotationConfigWebApplicationContext 从一个或多个基于Java的配置类中加载Spring Web应用上下文。
  • ClassPathXmlApplicationContext 从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源。
  • FileSystemXmlapplicationcontext 从文件系统下的一个或多个XML配置文件中加载上下文定义。
  • XmlWebApplicationContext 从Web应用下的一个或多个XML配置文件中加载上下文定义。

无论是从文件系统中装载应用上下文还是从类路径下装载应用上下文,将bean加载到bean工厂的过程都是相似的。例如,如下代码展示了如何加载一个FileSystemXmlApplicationContext:

      

  类似地,你可以使用ClassPathXmlApplicationContext 从应用的类路径下加载应用上下文:

      

  使用FileSystemXmlApplicationContext 和使用ClassPathXmlApp-licationContext 的区别在于:FileSystemXmlApplicationContext 在指定的文件系统路径下查找knight.xml文件;而ClassPathXmlApplicationContext 是在所有的类路径(包含JAR文件)下查找 knight.xml文件。

  应用上下文准备就绪之后,我们就可以调用上下文的getBean() 方法从Spring容器中获取bean。

2.2 bean的生命周期

  在传统的Java应用中,bean的生命周期很简单。使用Java关键字new进行bean实例化,然后该bean就可以使用了。一旦该bean不再被使用,则由Java自动进行垃圾回收。

  相比之下,Spring容器中的bean的生命周期就显得相对复杂多了。正确理解Spring bean的生命周期非常重要,因为你或许要利用Spring提供的扩展点来自定义bean的创建过程。下图展示了bean装载到Spring应用上下文中的一个典型的生命周期过程。

      

正如你所见,在bean准备就绪之前,bean工厂执行了若干启动步骤。我们对上图进行详细描述:

  • 1.Spring对bean进行实例化;
  • 2.Spring将值和bean的引用注入到bean对应的属性中;
  • 3.如果bean实现了BeanNameAware 接口,Spring将bean的ID传递给setBean-Name() 方法;
  • 4.如果bean实现了BeanFactoryAware 接口,Spring将调用setBeanFactory() 方法,将BeanFactory容器实例传入;
  • 5.如果bean实现了ApplicationContextAware 接口,Spring将调用setApplicationContext() 方法,将bean所在的应用上下文的引用传入进来;
  • 6.如果bean实现了BeanPostProcessor 接口,Spring将调用它们的post-ProcessBeforeInitialization() 方法;
  • 7.如果bean实现了InitializingBean 接口,Spring将调用它们的after-PropertiesSet() 方法。类似地,如果bean使用init-method 声明了初始化方法,该方法也会被调用;
  • 8.如果bean实现了BeanPostProcessor 接口,Spring将调用它们的post-ProcessAfterInitialization() 方法;
  • 9.此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;
  • 10.如果bean实现了DisposableBean 接口,Spring将调用它的destroy() 接口方法。同样,如果bean使用destroy-method 声明了销毁方法,该方法也会被调用。

3. 俯瞰Spring风景线

3.1 Spring模块

在Spring 4.0中,Spring框架的发布版本包括了20个不同的模块,每个模块会有3个JAR文件(二进制类库、源码的JAR文件以及JavaDoc的JAR文件)。

                  

这些模块依据其所属的功能可以划分为6类不同的功能:

            

3.2 Spring Portfolio

  Spring远不是Spring框架所下载的那些。如果仅仅停留在核心的Spring框架层面,我们将错过Spring Portfolio所提供的巨额财富。整个Spring Portfolio包括多个构建于核心Spring框架之上的框架和类库。概括地讲,整个Spring Portfolio几乎为每一个领域的Java开发都提供了Spring编程模型。

(一)《Spring实战》——Spring核心的更多相关文章

  1. spring实战 — spring数据库事务

    欢迎加入程序员的世界,添物科技为您服务. 欢迎关注添物网的微信(微信号:tianwukeji),微博(weibo.com/91tianwu/),或下载添物APP,及时获取最新信息. 免费加入QQ群:5 ...

  2. 【Spring实战】--1Spring的核心

    最近面试总会涉及Spring的优点,SpringMVC与Struts2的比较,生活慢慢稳定下来,这些面试还是应了那句话“只顾盲目拉车,不会低头看路”,回过头来还是要好好研究一下Spring,如果仅仅是 ...

  3. Spring实战——缓存

    缓存 提到缓存,你能想到什么?一级缓存,二级缓存,web缓存,redis-- 你所能想到的各种包罗万象存在的打着缓存旗号存在的各种技术或者实现,无非都是宣扬缓存技术的优势就是快,无需反复查询等. 当然 ...

  4. Spring Boot 最核心的 25 个注解,都是干货!

    学习和应用 Spring Boot 有一些时间了,你们对 Spring Boot 注解了解有多少呢?今天栈长我给大家整理了 Spring Boot 最核心的 25 个注解,都是干货! 你所需具备的基础 ...

  5. Spring Boot 最核心的 3 个注解详解

    最近面试一些 Java 开发者,他们其中有些在公司实际用过 Spring Boot, 有些是自己兴趣爱好在业余自己学习过.然而,当我问他们 Spring Boot 最核心的 3 个注解是什么,令我失望 ...

  6. 《Spring实战》学习笔记-第五章:构建Spring web应用

    之前一直在看<Spring实战>第三版,看到第五章时发现很多东西已经过时被废弃了,于是现在开始读<Spring实战>第四版了,章节安排与之前不同了,里面应用的应该是最新的技术. ...

  7. Spring实战第一部分总结

                                                         Spring实战第一部分总结 第一章 综述 1. DI依赖注入让相互协作的组件保持松散耦合,而 ...

  8. Spring实战第八章学习笔记————使用Spring Web Flow

    Spring实战第八章学习笔记----使用Spring Web Flow Spring Web Flow是一个Web框架,它适用于元素按规定流程运行的程序. 其实我们可以使用任何WEB框架写流程化的应 ...

  9. Spring实战第一章学习笔记

    Spring实战第一章学习笔记 Java开发的简化 为了降低Java开发的复杂性,Spring采取了以下四种策略: 基于POJO的轻量级和最小侵入性编程: 通过依赖注入和面向接口实现松耦合: 基于切面 ...

随机推荐

  1. PAT甲级1034. Head of a Gang

    PAT甲级1034. Head of a Gang 题意: 警方找到一个帮派的头的一种方式是检查人民的电话.如果A和B之间有电话,我们说A和B是相关的.关系的权重被定义为两人之间所有电话的总时间长度. ...

  2. Struts+HIbernate+Spring

    1.Struts 取代JSP中的控制功能,为系统添加独立的控制,采用Struts引入标签,实现JSP与后台JAVA代码的分离,JSP只负责显示,与struts.xml配合实现页面跳转 实现:接收请求, ...

  3. CentOS 6.9搭建的网关服务器不经过静态路由表的问题解决(没有开启路由转发功能)

    场景: 1.使用CentOS 6.9搭建的网关服务器,下面的机器都设置用这个网关,搭建参考:http://www.cnblogs.com/EasonJim/p/8289618.html 2.配置了静态 ...

  4. object-c的http post请求之 ASIFormDataRequest使用

    ASIHTTPRequest类库中的ASIFormDataRequest是实现HTTP协议中的处理POST表单的很好的类库.使用起来非常简单. 在说明之前先需要了解HTTP请求的Get和Post方法. ...

  5. Mosfet Bi-Directional Switch NMOS PMOS Back to Back

    http://www.electronic-products-design.com/geek-area/electronics/mosfets/using-mosfets-as-general-swi ...

  6. Druid 连接泄漏监测

    当程序存在缺陷时,申请的连接忘记关闭,这时候,就存在连接泄漏了.Druid提供了RemoveAbandanded相关配置,用来关闭长时间不使用的连接.例如: 配置 <bean id=" ...

  7. vagrant多节点配置

    1.vagrantfile的配置 Vagrant.configure("2") do |config| config.vm.box = "xinjieLinux" ...

  8. Windows上的git配置

    Git下载: 网站:https://code.google.com/p/msysgit/ 文件:https://msysgit.googlecode.com/files/Git-1.8.4-previ ...

  9. serverbash漏洞修补日记——2014/09/30

    近期bash漏洞在网上闹得沸沸扬扬的,我也修补一下.以防万一. 须要用到的命令: 查看操作系统版本号:cat /etc/issue 查看bash版本号:bash -version 查看操作系统是64位 ...

  10. VB开发ActiveX控件的一些记录

    注意,下面很多语句的用法,不能放在Private Sub UserControl_Initialize()里使用,要放在Private Sub UserControl_InitProperties() ...