Spring实战笔记——(1)Spring之旅(上)

Spring实战笔记——(1)Spring之旅

1.1简化Java开发

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

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

1.1.1 激发POJO的潜能

很多框架通过强迫应用继承它们的类或实现它们的接口从而导致应用与框架绑死。Spring不会强迫你实现Spring 规范的接口或继承Spring规范的类,相反,在基于Spring构建的应用中,它的类通常没有任何痕迹表明你使用了Spring。最坏的场景是,一个类或许会使用Spring注解,但它依旧是POJO。
He11oworldBean类为例:

public class HelloWorldBean{
public string sayHello(){
return"Hello World"}
}

就是普通的POJO,看不出是Spring组件。然而Spring的非侵入编程模型意味着这个类在Spring应用和非Spring应用中都可以发挥同样的作用。
其中Spring通过DI依赖注入就是赋予其成Spring组件的能力,实现对象彼此之间保持松散耦合的。

1.1.2依赖注入

一般的应用都会由两个或者更多的类组成,这些类相互之间进行协作来完成特定的业务逻辑。按照传统的做法,每个对象负责管理与自己相互协作的对象(即它所依赖的对象)的引用,这将会导致高度耦合和难以测试的代码。

依赖注入的实现

public class DamselRescuingknight implements Knight{
private RescueDamselQuest quest;
public DamselRescuingknight(){
//与RescueDamselQuest紧糊合
this.quest=new RescueDamselQuest();
}
 public void embarkonQuest(){
quest.embark();
}
}

构造函数中自行创建了Rescue DamselQuest。这使得DamselRescuingKnight 紧密地和RescueDamselQuest耦合到了一起,因此极大地限制了这个骑士执行探险的能力。如果一个少女需要救援,这个骑士能够召之即来。但是如果一条恶龙需要杀掉那么这个骑士就爱莫能助了。更糟糕的是,为这个Damse1Rescuingknight编写单元测试将出奇地困难。在这样的一个测试中,你必须保证当骑士的embarkonQuest()方法被调用的时候,探险的embark()方法也要被调用。

​ 耦合具有两面性(two-headed beast)。一方面,紧密耦合的代码难以测试、难以复用、难以理解,并且典型地表现出“打地鼠”式的bug特性(修复一个bug,将会出现一个或者更多新的bug)。另一方面,一定程度的耦合又是必须的——完全没有耦合的代码什么也做不了。为了完成有实际意义的功能,不同的类必须以适当的方式进行交互。总而言之,耦合是必须的,但应当被小心谨慎地管理。

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

构造器注入
public class BraveKnight implements Knight {

  private Quest quest;
//Quest被注入进来
  public BraveKnight(Quest quest) {
    this.quest = quest;
  }

  public void embarkOnQuest() {
    quest.embark();
  }

}

不同于之前的Damse1RescuingKnightBraveKnight没有自行创建探险任务,而是在构造的时候把探险任务作为构造器参数传入。这是依赖注入的方式之一,即构造器注入(constructor injection)。
这里的要点是Braveknight没有与任何特定的Quest实现发生耦合。对它来说,被要求挑战的探险任务只要实现了Quest接口,那么具体是哪种类型的探险就无关紧要了。这就是DI所带来的最大收益——松耦合。如果一个对象只通过接口(而不是具体实现或初始化过程)来表明依赖关系,那么这种依赖就能够在对象本身毫不知情的情况下,用不同的具体实现进行替换。对依赖进行替换的一个最常用方法就是在测试的时候使用mock实现。

XMl注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans.xsd">
    
  <bean id="knight" class="com.knights.BraveKnight">
    <constructor-arg ref="quest" />
  </bean>

  <bean id="quest" class="com.knights.SlayDragonQuest">
    <constructor-arg value="#{T(System).out}" />
  </bean>

</beans>

BraveknightSlayDragonQuest被声明为Spring中的bean。就Braveknight bean 来讲,它在构造时传入了对slayDragonQuest bean的引用,将其作为构造器参数。同时,slayDragonQuest bean的声明使用了Spring表达式语言(Spring Expression Language),将System.out(这是一个PrintStream)传入到了slayDragonQuest的构造器中。

//现在BraveKnight类可以接受你传递给它的任意一种Quest的实现,假设,希望Braveknight所要进行探险任务是杀死一只怪龙
import java.io.PrintStream;
public class SlayDragonQuest implements Quest {
  private PrintStream stream;

  public SlayDragonQuest(PrintStream stream) {
    this.stream = stream;
  }

  public void embark() {
    stream.println("Embarking on quest to slay the dragon!");
  }

}

Java的配置注解注入
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.springinaction.knights.Braveknight;
import com.springinaction.knights.Knight;
import com.springinaction.knights.Quest;
import com.springinaction.knights.SlayDragonQuest; @Configuration
public class KnightConfig{
    @ Bean
    public Knight knight(){
return new Braveknight(quest();
    }
    @Bean
    public Quest quest(){
        return new SlayDragonQuest(System.out);
    }
 }
如何工作的

Spring通过应用上下文(Application Context)装载bean的定义并把它们组装起来。Spring应用上下文全权负责对象的创建和组装。Spring自带了多种应用上下文的实现,它们之间主要的区别仅仅在于如何加载配置。用XML配置的,所以选择ClassPathxmlApplicationContext作为应用上下文相对是比较合适的。该类加载位于应用程序类路径下的一个或多个XML配置文件。


import org.springframework.context.support.
                   ClassPathXmlApplicationContext;
/**
 加载包含Knight的Spring上下文
**/
public class KnightMain {

  public static void main(String[] args) throws Exception {
      //1.加载Spring上下文    
      ClassPathXmlApplicationContext context = 
        new ClassPathXmlApplicationContext(
            "META-INF/spring/knight.xml");
      //获取bean
    Knight knight = context.getBean(Knight.class);
     //使用bean
    knight.embarkOnQuest();
    context.close();
  }
}

1.1.3应用切面

面向切面编程(aspect-oriented programming,AOP)允许你把遍布应用各处的功能分离出来形成可重用的组件。
面向切面编程往往被定义为促使软件系统实现关注点的分离一项技术。系统由许多不同的组件组成,每一个组件各负责一块特定功能。除了实现自身核心的功能之外,这些组件还经常承担着额外的职责。诸如日志、事务管理和安全这样的系统服务经常融入到自身具有核心业务逻辑的组件中去,这些系统服务通常被称为横切关注点,因为它们会跨越系统的多个组件。
如果将这些关注点分散到多个组件中去,代码将会带来双重的复杂性。

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

图中左边的业务对象与系统级服务结合得过于紧密。每个对象不但要知道它需要记日志、进行安全控制和参与事务,还要亲自执行这些服务。在整个系统内,关注点(例如日志和安全)的调用经常散布到各个模块中,而这些关注点并不是模块的核心业务

AOP能够使这些服务模块化,并以声明的方式将它们应用到它们需要影响的组件中去。所造成的结果就是这些组件会具有更高的内聚性并且会更加关注自身的业务,完全不需要了解涉及系统服务所带来复杂性。总之,AOP能够确保POJO的简单性。如下图示,可以把切面想象为覆盖在很多组件之上的一个外壳。应用是由那些实现各自业务功能的模块组成的。借助AOP,可以使用各种功能层去包裹核心业务层。这些层以声明的方式灵活地应用到系统中,核心应用甚至根本不知道它们的存在。可以将安全、事务和日志关注点与核心业务逻辑相分离。
在这里插入图片描述

以吟游诗人用诗歌记载骑士的事迹并传唱为例,把吟游诗人看做服务类来记载骑士的所有事迹。

import java.io.PrintStream;

public class Minstrel {

  private PrintStream stream;
  
  public Minstrel(PrintStream stream) {
    this.stream = stream;
  }

  public void singBeforeQuest() {
      //探险前调用
    stream.println("Fa la la, the knight is so brave!");
  }

  public void singAfterQuest() {
      //探险之后调用
    stream.println("Tee hee hee, the brave knight " +
    		"did embark on a quest!");
  }

}

在骑士执行每一个探险任务之前,singBeforeQuest()方法会被调用;在骑士完成探险任务之后,singAfterQuest()方法会被调用。在这两种情况下,Minstrel都会通过一个Printstream类来歌颂骑士的事迹,这个类是通过构造器注入进来的。


利用AOP,可以声明吟游诗人必须歌颂骑士的探险事迹,而骑士本身并不用直接访问Minstrel的方法。要将Minstrel抽象为一个切面,在Spring配置文件中声明它。那么Minstrel就将被声明为一个切面。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xsi:schemaLocation="http://www.springframework.org/schema/aop 
      http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="knight" class="com.knights.BraveKnight">
    <constructor-arg ref="quest" />
  </bean>

  <bean id="quest" class="com.knights.SlayDragonQuest">
    <constructor-arg value="#{T(System).out}" />
  </bean>

  <bean id="minstrel" class="com.knights.Minstrel">
    <constructor-arg value="#{T(System).out}" />
  </bean>

  <aop:config>
    <aop:aspect ref="minstrel">
      <aop:pointcut id="embark"
          expression="execution(* *.embarkOnQuest(..))"/>
        
      <aop:before pointcut-ref="embark" 
          method="singBeforeQuest"/>

      <aop:after pointcut-ref="embark" 
          method="singAfterQuest"/>
    </aop:aspect>
  </aop:config>
  
</beans>

本xml中使用了Spring的aop配置命名空间把Minstrelbean声明为一个切面。首先,需要把Minstrel声明为一个bean,然后在aop:aspect元素中引用该bean。为了进一步定义切面,声明(使用aop:before)在embarkonQuest()方法执行前调用Minstrel的singBeforeQuest()方法。这种方式被称为前置通知(before advice).同时声明(使用aop:after)在embarkOnQuest()方法执行后调用singAfter Quest()方法。这种方式被称为后置通知(after advice)。在这两种方式中,pointcut-ref属性都引用了名字为embank的切入点。该切入点是在前边的元素中定义的,并配置expression属性来选择所应用的通知。表达式的语法采用的是AspectJ的切点表达式语言。Spring在骑士执行探险任务前后会调用Minstrel的singBeforeQuest()和singAfterQuest()方法。

由此可以得出两个观点,

  • Minstrel仍然是一个POJO,没有任何代码表明它要被作为一个切面使用。当我们按照上面那样进行配置后,在Spring的上下文中,Minstrel实际上已经变成一个切面了。
  • Minstrel可以被应用到Braveknight中,而Braveknight不需要显式地调用它。实际上,Braveknight 完全不知道Minstrel的存在。必须还要指出的是,尽管我们使用Spring 把Minstrel转变为一个切面,但首先要把它声明为一个Spring bean。能够为其他Spring bean做到的事情都可以同样应用到Spring切面中,例如为它们注入依赖。

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

其实有时我们都在重复的写着相同的代码。样板式代码的常见范例是使用JDBC访问数据库查询数据。在许多编程场景中往往都会导致类似的样板式代码,JMS、JNDI和使用REST服务通常也涉及大量的重复代码。Spring 旨在通过模板封装来消除样板式代码。Spring的Jdbc Template 使得执行数据库操作时,避免传统的JDBC样板代码成为了可能。

1.2容纳你的Bean

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

理解容器

容器是Spring框架的核心。Spring容器使用DI管理构成应用的组件,它会创建相互协作的组件之间的关联。这些对象更简单干净,更易于理解,更易于重用并且更易于进行单元测试。Spring 容器并不是只有一个。Spring自带了多个容器实现,可以归为两种不同的类型:

  1. bean工厂(由org.springframework.beans.factory.eanFactory 接口定义)是最简单的容器,提供基本的DI支持。

  2. 应用上下文(由org.springframework.context.ApplicationContext接口定义)基于BeanFactory构建,并提供应用框架级别的服务,例如从属性文件解析文本信息以及发布应用事件给感兴趣的事件监听者。

    但bean工厂对大多数应用来说往往太低级了,因此,应用上下文更广泛应用。

1.2.1使用应用上下文

Spring自带了多种类型的应用上下文。

  • AnnotationConfigApplicationContext:从一个或多个基于Java的配置类中加载Spring应用上下文。

  • AnnotationConfigwebApplicationContext:从一个或多个基于Java的配置类中加载Spring Web应用上下文。

  • ClassPathxmlApplicationContext:从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源。

  • FileSystemxmlapplicationcontext:从文件系统下的一个或多个XML配置文件中加载上下文定义。

  • XmlWebApplicationContext:从Web应用下的一个或多个XML配置文件中加载上下文定义。


    从文件系统中装载应用上下文还是从类路径下装载应用上下文,将bean加载到bean工厂的过程都是相似的。例如:

//加载FileSystemXmlApplicationContext:
ApplicationContext context=new FileSyatemxmlApplicationcontext("c:/knight.xml");

类似地,你可以使用ClassPathxmlApplicationContext从应用的

//类路径下加载应用上下文:
Applicationcontext context=new ClassPathxmlApplicationcontext"knight.xml");

使用FilesystemxmlApplicationContext 和使用ClassPathXmlApp-
1icationContext的区别在于:FileSystemxmlApplicationContext在指定的文件系统路径下查找knight.xml文件;而ClassPathxmlApplicationcontext是在所有的类路径(包含JAR文件)下查找knight.xml文件。
如果你想从Java配置中加载应用上下文,那么可以使用AnnotationConfig-
ApplicationContext:


Applicationcontext context=new AnnotationconfigApplicationContext(
com.springinaction.knights.config.Knightconfig.class);

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

1.2.2bean的生命周期

在传统的Java应用中,使用Jnew进行bean实例化,然后该bean就可以使用了。一旦该bean不再被使用,则由Java自动进行垃圾回收。图下面展示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声明了销毁方法,该方法也会被调用。

1.3俯瞰 Spring 风景线

Spring框架关注于通过DI、AOP和消除样板式代码来简化企业级Java开发。
但在Spring框架之外还存在一个构建在核心框架之上的庞大生态圈,它将Spring扩展到不同的领域,例如Web服务、REST、移动开发以及NoSQL。
首先让我们拆开Spring框架的核心。

1.3.1Spring模块

在Spring4.0中,Spring框架的发布版本包括了20个不同的模块,每个模块会有3个JAR文件(二进制类库、源码的JAR文件以及JavaDoc的JAR文件)。这些模块依据其所属的功能可以划分为6类不同的功能.。事实上,Spring甚至提供了与其他第三方框架和类库的集成点,这样你就不需要自己编写这样的代码了
在这里插入图片描述
spring-overview

Spring 核心容器
容器是Spring框架最核心的部分,它管理着Spring应用中bean的创建、配置和管理。在该模块中,包括了Spring bean工厂,它为Spring提供了DI的功能。核心容器由spring-core,spring-beans,spring-context,spring-context-support和spring-expression(SpEL,Spring表达式语言,Spring Expression Language)等模块组成,细节如下:

  • spring-core模块提供了框架的基本组成部分,包括 IoC 和依赖注入功能。

  • spring-beans 模块提供 BeanFactory,工厂模式的微妙实现,它移除了编码式单例的需要,并且可以把配置和依赖从实际编码逻辑中解耦。

  • context模块建立在由core和 beans 模块的基础上建立起来的,它以一种类似于JNDI注册的方式访问对象。Context模块继承自Bean模块,并且添加了国际化(比如,使用资源束)、事件传播、资源加载和透明地创建上下文(比如,通过Servelet容器)等功能。Context模块也支持Java EE的功能,比如EJB、JMX和远程调用等。ApplicationContext接口是Context模块的焦点。spring-context-support提供了对第三方库集成到Spring上下文的支持,比如缓存(EhCache, Guava, JCache)、邮件(JavaMail)、调度(CommonJ, Quartz)、模板引擎(FreeMarker, JasperReports, Velocity)等。

  • spring-expression模块提供了强大的表达式语言,用于在运行时查询和操作对象图。它是JSP2.1规范中定义的统一表达式语言的扩展,支持set和get属性值、属性赋值、方法调用、访问数组集合及索引的内容、逻辑算术运算、命名变量、通过名字从Spring IoC容器检索对象,还支持列表的投影、选择以及聚合
    Spring的AOP模块
    在AOP模块中,Spring对面向切面编程提供了丰富的支持。这个模块是Spring应用系统中开发切面的基础。与DI一样,AOP可以帮助应用对象解耦。借助于AOP,可以将遍布系统的关注点(例如事务和安全)从它们所应用的对象中解耦出来。


数据访问与集成

数据访问/集成层包括 JDBC,ORM,OXM,JMS 和事务处理模块,细节如下:

(注:JDBC=Java Data Base Connectivity,ORM=Object Relational Mapping,OXM=Object XML Mapping,JMS=Java Message Service)

  • JDBC 模块提供了JDBC抽象层,它消除了冗长的JDBC编码和对数据库供应商特定错误代码的解析。

  • ORM 模块提供了对流行的对象关系映射API的集成,包括JPA、JDO和Hibernate等。通过此模块可以让这些ORM框架和spring的其它功能整合,比如前面提及的事务管理。

  • OXM 模块提供了对OXM实现的支持,比如JAXB、Castor、XML Beans、JiBX、XStream等。

  • JMS 模块包含生产(produce)和消费(consume)消息的功能。从Spring 4.1开始,集成了spring-messaging模块。。

  • 事务模块为实现特殊接口类及所有的 POJO 支持编程式和声明式事务管理。(注:编程式事务需要自己写beginTransaction()、commit()、rollback()等事务管理方法,声明式事务是通过注解或配置由spring自动处理,编程式事务粒度更细)


Web与远程调用

Web 层由 Web,Web-MVC,Web-Socket 和 Web-Portlet 组成,它们的细节如下:

  • Web 模块提供面向web的基本功能和面向web的应用上下文,比如多部分(multipart)文件上传功能、使用Servlet监听器初始化IoC容器等。它还包括HTTP客户端以及Spring远程调用中与web相关的部分。。

  • Web-MVC 模块为web应用提供了模型视图控制(MVC)和REST Web服务的实现。Spring的MVC框架可以使领域模型代码和web表单完全地分离,且可以与Spring框架的其它所有功能进行集成。

  • Web-Socket 模块为 WebSocket-based 提供了支持,而且在 web 应用程序中提供了客户端和服务器端之间通信的两种方式。

  • Web-Portlet 模块提供了用于Portlet环境的MVC实现,并反映了spring-webmvc模块的功能。

MVC(Model-View-Controller)模式是一种普遍被接受的构建Web应用的方法,它可以帮助用户将界面逻辑与应用逻辑分离。Apache的Struts、JSF、WebWork和Tapestry都是可选的最流行的MVC框架。虽然Spring能够与多种流行的MVC框架进行集成,但它的Web和远程调用模块自带了一个强大的SpringMVC框架,有助于在Web层提升应用的松耦合水平。该模块还提供了多种构建与其他应用交互的远程调用方案。Spring远程调用功能集成了RMl(Remote Method Invocation)、Hessian、Burlap、JAX-WS,同时Spring还自带了一个远程调用框架:HTTP invoker。Spring还提供了暴露和使用RESTAPI的良好支持。
Instrumentation

Spring的Instrumentation 模块提供了为JVM添加代理(agent)的功能。具体来讲,它为Tomcat提供了一个织入代理,能够为Tomcat传递类文件,就像这些文件是被类加载器加载的一样。
测试
Spring提供了测试模块以致力于Spring应用的测试。通过该模块,你会发现Spring为使用JNDI、Servlet和Portlet编写单元测试提供了一系列的mock对象实现。对于集成测试,该模块为加载Spring应用上下文中的bean集合以及与Spring上下文中的bean 进行交互提供了支持。
)、Hessian、Burlap、JAX-WS,同时Spring还自带了一个远程调用框架:HTTP invoker。Spring还提供了暴露和使用RESTAPI的良好支持。
Instrumentation

Spring的Instrumentation 模块提供了为JVM添加代理(agent)的功能。具体来讲,它为Tomcat提供了一个织入代理,能够为Tomcat传递类文件,就像这些文件是被类加载器加载的一样。
测试
Spring提供了测试模块以致力于Spring应用的测试。通过该模块,你会发现Spring为使用JNDI、Servlet和Portlet编写单元测试提供了一系列的mock对象实现。对于集成测试,该模块为加载Spring应用上下文中的bean集合以及与Spring上下文中的bean 进行交互提供了支持。

1.3.2Spring Portfolio


Spring Web Flow

Spring Web Flow建立于Spring MVC框架之上,它为基于流程的会话式Web应用(可以想一下购物车或者向导功能)提供了支持。


Spring Web Service

Spring Web Service虽然核心的Spring 框架提供了将Spring bean以声明的方式发布为Web Service的功能,
这些服务的契约由bean的接口来决定。Spring Web Service提供了契约优先的Web Service模型,服务的实现都是为了满足服务的契约而编写的。


Spring Security
Spring Security安全对于许多应用都是一个非常关键的切面。利用Spring AOP,Spring Security为Spring应用提供了声明式的安全机制。


Spring Integration

许多企业级应用都需要与其他应用进行交互。Spring Integration提供了多种通用应用集成模式的Spring声明式风格实现。


Spring Batch

当我们需要对数据进行大量操作时,没有任何技术可以比批处理更胜任这种场景。如果需要开发一个批处理应用,你可以通过Spring Batch,使用Spring 强大的面向 POJ0的编程模型。


Spring Data

Spring Data使得在Spring中使用任何数据库都变得非常容易。一种新的数据库种类,通常被称之为NoSQL数据库。不管你使用文档数据库,如MongoDB,图数据库,如Neo4j,还是传统的关系型数据库,Spring Data都为持久化提供了一种简单的编程模型。这包括为多种数据库类型提供了一种自动化的Repository机制,它负责为你创建Repository的实现。


Spring Social

社交网络是互联网领域中新兴的一种潮流,越来越多的应用正在融入社交网络网站,例如Facebook或者Twitter。Spring Social是Spring的一个社交网络扩展模块。不过,Spring Social并不仅仅是tweet和好友。尽管名字是这样,但Spring Social更多的是关注连接(connect),而不是社交(social)。它能够帮助你通过RESTAPI连接Spring应用,其中有些Spring应用可能原本并没有任何社交方面的功能目标。


Spring Mobile

Spring Mobile是Spring MVC新的扩展模块,用于支持移动Web应用开发。


Spring for Android

与Spring Mobile 相关的是Spring Android项目。这个新项目,旨在通过Spring框架为开发基于Android设备的本地应用提供某些简单的支持。最初,这个项目提供了Spring RestTemplate的一个可以用于Android应用之中的版本。它还能与Spring Social协作,使得原生应用可以通过RESTAPI进行社交网络的连接。


Spring Boot

Spring极大地简化了众多的编程任务,减少甚至消除了很多样板式代码,Spring Boot是一个崭新的令人兴奋的项目,它以Spring的视角,致力于简化Spring本身。Spring Boot大量依赖于自动配置技术,它能够消除大部分(在很多场景中,甚至是全部)Spring配置。它还提供了多个Starter项目,不管你使用Maven还是Gradle,这都能减少Spring工程构建文件的大小。

1.4Spring的新功能

Spring 4.0新特性

  • Spring提供了对WebSocket编程的支持,包括支持JSR-356—Java API for WebSocket;
  • 鉴于WebSocket仅仅提供了一种低层次的API,急需高层次的抽象,因此Spring4.0在WebSocket之上提供了一个高层次的面向消息的编程模型,该模型基于SockJS,并且包含了对STOMP协议的支持;
  • 新的消息(messaging)模块,很多的类型来源于Spring Integration项目。这个消息模块支持Spring的SockJS/STOMP功能,同时提供了基于模板的方式发布消息;
  • Spring是第一批(如果不说是第一个的话)支持Java8特性的Java框架,比如它所支持的lambda表达式。别的暂且不说,这首先能够让使用特定的回调接口(如RowMapper和JdbcTemplate)更加简洁,代码更加易读;
  • 与Java8同时得到支持的是JSR-310—Date与TimeAPl,在处理日期和时间时,它为开发者提供了比java.util.Date或java.util.Calendar更丰富的APl;
  • 为Groovy开发的应用程序提供了更加顺畅的编程体验,尤其是支持非常便利地完全采用Groovy开发Spring应用程序.随这些一起提供的是来自于Grails的BeanBuilder,借助它能够通过Groovy配置Spring应用;添加了条件化创建bean的功能,在这里只有开发人员定义的条件满足时,才会创建所声明的bean;
  • Spring 4.0包含了Spring RestTemplate的一个新的异步实现,它会立即返回并且允许在操作完成后执行回调;
  • 添加了对多项JE规范的支持,包括JMS2.0、JTA1.2、JPA2.1和Bean Vaidation 1.1.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值