(第二讲)Spring&Spring MVC&Spring Boot三者之间的区别与联系

图片描述
Spring Framework的诞生让开发人员的工做从石器时代跨域到了工业时代,你是否还能记起手撸Servlet和JDBC的岁月?,你是否还对Struts1以及Struts2莫名其妙的404错误记忆犹新?从2004年3月Spring 1.0发布到至今,Spring的发展已经走过了15个年头,其创造的价值让人瞩目。今天,带着这样一个背景来梳理一下Spring Framework,Spring MVC和Spring Boot三者之间的区别。html

咱们使用Spring家族的系列产品这么长时间,不由会问这样几个问题:Spring Framework是什么?Spring MVC是什么?Spring Boot又是什么?它们被设计出来的目的是什么?java

你须要了解的知识

在接下来的内容中,将梳理这样几个知识点:web

  • Spring Framework基本概述
  • Spring Framework主要解决的问题是什么?
  • Spring MVC基本概述
  • Spring MVC主要解决的问题是什么?
  • Spring Boot主要解决的问题是什么?
  • Spring,Spring MVC和Spring Boot三者之间的区别是什么?

Spring Framework 解决了哪些核心问题?

当你仔细思考这个问题的时候你会发现,不少地方它都有渗透到,貌似一个Spring就能够撑起开发的半边天,以致于很难一会儿回答这个问题。那Spring Framework到底解决了哪些核心问题?spring

Spring Framework最重要也是最核心的特性是依赖注入。全部的Spring模块的核心就是DI(依赖注入)或者IoC(控制反转)。

依赖注入或控制反转是Spring Framework最大的特性,当咱们正确使用DI(依赖注入)或IoC时,能够开发出一个高内聚低耦合的应用程序,而这一一个低耦合的应用程序能够轻松的对其实施单元测试。这就是Spring Framework解决的最核心的问题。数据库

无依赖注入

请考虑这一一个案例:UserAction依赖于UserService来获取用户信息,在没有依赖注入的状况下,咱们须要手动在UserAction中实例化一个UserService对象,这样的手工做业意味着UserAction和UserService必须精密的联系在一块儿,才能正常工做。若是一个Action须要多个Service提供服务,那实例化这些Service将是一个繁重的工做。下面咱们给出一个不使用依赖注入的代码片断加以说明:设计模式

UserService.java跨域

public interface UserService{
    User profile();
}

UserServiceImpl.javatomcat

public class UserServiceImpl implements UserService{
    @Override
    User profile(){
        // TODO
    }
}

UserAction.javaspringboot

@RestController
public class UserAction{
    
    private UserService userService = new UserServiceImpl();
    // other services...
    
    @GetMapping("/profile")
    public User profile(){
        return userService.profile();
    }
}

引入依赖注入

引入依赖注入将会使整个代码看起来很清爽。为了可以开发出高内聚低耦合的应用程序,Spring Framework为咱们作了大量的准备工做。下面咱们使用两个简单的注解@Component@Autowired来实现依赖注入。服务器

  • @Component : 该注解将会告诉Spring Framework,被此注解标注的类须要归入到Bean管理器中。
  • @Autowired : 告诉Spring Framework须要找到一与其类型匹配的对象,并将其自动引入到所须要的类中。

在接下来的示例代码中,咱们会看到Spring Framework将为UserService建立一个Bean对象,并将其自动引入到UserAction中。

UserService.java

public interface UserService{
    User profile();
}

UserServiceImpl.java

@Component
public class UserServiceImpl implements UserService{
    @Override
    User profile(){
        // TODO
    }
}

UserAction.java

@RestController
public class UserAction{
    @Autowired
    private UserService userService;
    // other services...
    
    @GetMapping("/profile")
    public User profile(){
        return userService.profile();
    }
}

对比上下两部分的代码,你是否发现了他们之间的区别?Action所依赖的Service的初始化工做所有交由Spring Framework来管理,咱们只须要在适当的地方向Spring Framework索取想要服务便可。这就比如当我想要吃薯片的时候,我不须要本身亲自种土豆,施肥,收获...清洗,切片...一直到最后炸土豆片,想一想都以为累,而更简单的方法是直接去超市购买本身想要的薯片便可。

Spring Framework还有其余的核心特性吗?

1:衍生的特性

Spring Framework的依赖注入是核心中的核心,在依赖注入核心特性的基础上,Spring Framework还衍生出了不少的高级模块:

  • Spring JDBC
  • Spring MVC
  • Spring AOP
  • Spring ORM
  • Spring JMS
  • Spring Test

对于这些新的高级模块,可能会产生这一一个问题:它们是不是一个全新的功能?答案是否认的,在不使用Spring Framework的状况下,咱们依然可以使用JDBC链接数据库,依然可以对视图和数据模型进行控制,依然可以使用第三方的ORM框架。那Spring Framework干了什么?Spring Framework站在巨人的肩膀上,对这些原生的模块进行了抽象,而抽象能够带来这样一些好处:

  • 减小了应用中模板代码的数量
  • 下降了原生框架的技术门槛
  • 基于依赖注入特性,实现了代码的解耦,真正的高内聚、低耦合
  • 更细粒度的单元测试

这样的好处是显而易见的,好比与传统的JDBC相比,使用JDBCTemplate操做数据库,首先是代码量小了,其次是咱们不须要再面对恐怖的try-catch。

2:优秀的集成能力

Spring Framework还具有另一个重要特性,那就是可以快速的与其余三方框架进行整合。与其本身造轮子,还不如想办法将好的轮子整合在一块儿,我想这句话应该能够用来概况Spring Framework这一特性。Spring Framework对于整合其余的框架,给出了不错的解决方案,下面将列举一些常见的方案:

  • 与Hibernate ORM框架整合
  • 与MyBatis 对象映射框架整合
  • 与Junit单元测试框架整合
  • 与Log4J日志记录框架整合

Spring MVC是什么?

Spring MVC提供了构建Web应用程序的全功能MVC模块,实现了Web MVC设计模式以及请求驱动类型的轻量级Web框架,即采用了MVC架构模式的思想,将Web层进行职责解耦。基于请求驱动指的是使用请求-响应模型,视图与数据模型分离,以简化Web应用的开发。

使用Spring MVC提供的Dispatcher Servlet,ModelAndView和ViewResolver等功能,能够轻松的开发出一个Web应用程序。

Spring Boot出现的缘由是什么?

咱们都知道,使用Spring Framework来开发应用程序,须要进行大量的配置工做以及依赖包的管理,工做繁重并且极易出现配置错误,尤其明显的是依赖包之间的版本冲突问题。

举一个简单的案例,当咱们使用Spring MVC来开发Web应用程序时,咱们大体须要经历这样几个步骤:

  • 1:配置组件扫描的包路径

  • 2:配置对应的Servlet程序

  • 3:配置视图解析器

  • 4:配置页面模板引擎(JSP、Freemarker等)

下面给出了一个小范围的举例:

...
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/pages</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>
<mvc:resources mapping="/static/**" location="/static/"/>
...

此外,咱们还须要配置先关的Servlet处理程序,它们大体是这样的:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/todo-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

若是咱们的应用程序还须要连接数据,则还须要配置数据源,实体对象管理器,事务管理器等众多配置:

<bean id="datasource" class="">
    ...
</bean>
<bean id="entityManagerFactory" class="">
    ...
</bean>
<bean id="transactionManager" class="">
    ...
</bean>
...

面对众多的配置文件,咱们须要花费大量的时间去处理,这时你可能会问,我为何要花费那么多的时间去管理Spring的配置工做?不是应该专一于应用自己的业务逻辑吗?如今,有了Spring Boot,这些烦心事就不须要你去操心了。

1:Spring Boot的自动化配置能力

我为何会把Spring Boot的自动化配置能力放在第一位,由于它极大的下降了咱们使用Spring Framework所付出的成本。这是Spring Boot的自动化配置是一个最具价值的解决方案。

这难道不值得咱们拍案叫好吗?若是你想要开发一个Web应用程序,你须要作的事情就是将Spring Boot Web包引入到项目的类路径下,Spring Boot就能够帮你解决后续的大多数配置工做。
  • 若是Hibernate的依赖被放到了类路径上,Spring Boot会自动配置数据源
  • 若是Spring MVC的依赖被放到了类路径上,Spring Boot又会自动配置Dispatcher Servlet

当Spring Boot检测到有新的依赖包添加到类路径上,Spring Boot会采用默认的配置对新的依赖包进行设置,若是咱们想本身配置依赖包时,只须要手动覆盖默认的配置项便可。

  1. Spring Boot扫描类路径上可用的框架信息
  2. 获取应用程序现有的配置信息
  3. 若是应用程序没有提供框架的配置信息,Spring Boot将采用默认的配置来配置框架,这就是Spring Boot的自动配置特性(Auto Configuration)

2:Spring Boot Starter项目

在传统模式的开发过程当中,咱们须要反复的确认应用程序所须要的第三方JAR包,以及这些JAR的版本和依赖关系。例如,如今咱们打算开发一款Web应用程序,应用程序大概须要以下的一些依赖包:Spring MVC,Jackson Databind(用于数据绑定),Hibernate-Validator(用于服务端的数据校验)和Log4j(用于日志记录)。如今,咱们须要去下载对应的jar包到应用程序中,而且还须要处理依赖包之间版本冲突的问题。

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>4.2.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.3</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.0.2.Final</version>
</dependency>

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

这不是一件简单的事情,特别是发生版本冲突的时候,让应用程序可以正常运行起来就须要花费必定的时间。

Spring Boot Starter是一组用于管理依赖关系的描述符,经过这些描述符,咱们能够在应用程序中轻松的管理依赖包,你能够以开箱即用的方式获取想要的依赖包,而无需去Maven仓库总检索对应的依赖,并将依赖配置复制粘贴到应用程序的pom文件中。例如,若是你想要使用Spring和JPA进行数据库访问,只须要在pom中添加spring-boot-starter-data-jpa依赖项就能够。

如今,若是咱们想要开发一个Web应用程序,使用Spring Boot Starter Web依赖会是一个不错的选择。咱们能够经过使用Spring INitializr快速构建一个Web应用程序,并将Spring Boot Starter Web添加到项目中。此时咱们的pom文件只须要不多的配置:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Spring Boot Starter Web会为咱们预装以下的一些依赖:

  • Spring : core,beans,context,aop
  • Web MVC : Spring MVC
  • Jackson : JSON Binding
  • Validation : Hibernate Validator,Validation API
  • Embedded Servlet Container: Tomcat
  • Logging : logback,slf4j

对于开发人员而言,咱们不须要去担忧这些依赖项的管理工做以及解决他们之间的兼容性问题,Spring Boot已经帮咱们解决了。

Spring Boot的核心目标

Spring Boot的核心目标在于快速实现生产就绪的应用程序,这将包含这样几个部分:

  • 执行器 : 启用高级监控和跟踪应用程序功能
  • 嵌入式服务器:Spring Boot已经内置了多个Web服务器,如Undertow,jetty,tomcat,所以咱们不须要再额外的配置服务器,就能够完成应用程序的调试工做。
  • 默认的异常处理机制
  • 开箱即用的依赖项管理机制
  • 自动化配置

总结

经过上述的梳理,咱们能够看到,Spring Framework是一个提供了DI(依赖注入)和IoC(控制反转)的开发框架,使用Spring Framework能够帮助咱们开发出高内聚,低耦合的应用程序,Spring MVC是在Spring Framework基础上发展出来的基于MVC模式的全功能Web开发框架,实现了Model,View和Controller之间的职责解耦;Spring Boot为咱们提供了一个可以快速使用Spring Framework的优秀解决方案,经过最小化的配置,咱们就可使用Spring Framework,严格意义上讲,Spring Boot并非某种框架,它只是为开发人员提供了一个更好的更方便的使用Spring Framework的解决方案。

做者:谭朝红
原文:Spring&Spring MVC&Spring Boot三者之间的区别与联系

转载请联系做者本人,未经容许,请勿作任何商业行为

相关文章
相关标签/搜索