【Spring MVC和Spring Boot的关系】

时间:2023-02-21 11:22:11

Spring框架就像一个家族,有众多衍生产品例如boot、security、jpa等等。但他们的基础都是Spring的ioc和aop。ioc提供了依赖注入的容器,aop解决了面向横切面的编程;然后在此二者的基础上实现了其他延伸产品的高级功能。

Spring MVC是基于 Servlet 的一个 MVC 框架,主要解决 WEB 开发的问题。

后来因为 Spring 的配置非常复杂,各种XML、 JavaConfig处理起来比较繁琐。于是为了方便开发者使用,从而又推出了Spring BOOT,简化了Spring的配置流程。

说得更简便一些:Spring 最初利用“工厂模式”(DI)和“代理模式”(AOP)解耦应用组件。大家觉得挺好用,于是按照这种模式搞了一个MVC框架(一些用Spring解耦的组件),用来开发web应用,最终形成了SpringMVC。然后有发现每次开发都写很多样板代码,为了简化工作流程,于是开发出了一些“懒人整合包”(starter),这套就是 Spring BOOT。


Spring MVC的功能

Spring MVC提供了一种轻度耦合的方式来开发web应用。

Spring MVC是Spring的一个模块,一个web框架。通过Dispatcher Servlet、ModelAndView 和 View Resolver,开发web应用变得很容易。解决的问题领域是网站应用程序或者服务开发——URL路由、Session、模板引擎、静态Web资源等等。


Spring BOOT的功能

Spring Boot实现了自动配置,降低了项目搭建的复杂度。

众所周知Spring框架需要进行大量的配置,Spring Boot引入自动配置的概念,让项目设置变得很容易。Spring Boot本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于Spring框架的应用程序。也就是说,它并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具。同时它集成了大量常用的第三方库配置(例如Jackson, JDBC, Mongo, Redis, Mail等等),Spring Boot应用中这些第三方库几乎可以零配置的开箱即用(out-of-the-box),大部分的Spring Boot应用都只需要非常少量的配置代码,使开发者能够更加专注于业务逻辑。

Spring Boot只是承载者,辅助你简化项目搭建过程的。如果承载的是WEB项目,使用Spring MVC作为MVC框架,那么工作流程和你上面描述的是完全一样的,因为这部分工作是Spring MVC做的而不是Spring Boot。

对使用者来说,换用Spring Boot以后,项目初始化方法变了,配置文件变了,另外就是不需要单独安装Tomcat这类容器服务器了,maven打出jar包直接跑起来就是个网站,但你最核心的业务逻辑实现与业务流程实现没有任何变化。

所以,用最简练的语言概括就是:

Spring 是一个“引擎”;

Spring MVC 是基于Spring的一个 MVC 框架 ;

Spring Boot 是基于Spring4的条件注册的一套快速开发整合包。


什么是Spring?它解决了什么问题?

我们说到Spring,一般指代的是Spring Framework,它是一个开源的应用程序框架,提供了一个简易的开发方式,通过这种开发方式,将避免那些可能致使代码变得繁杂混乱的大量的业务/工具对象,说的更通俗一点就是由框架来帮你管理这些对象,包括它的创建,销毁等,比如基于Spring的项目里经常能看到的​​Bean​​,它代表的就是由Spring管辖的对象。

而在被管理对象与业务逻辑之间,Spring通过IOC(控制反转)架起使用的桥梁,IOC也可以看做Spring最核心最重要的思想,通过IOC能带来什么好处呢?首先来看一个实际开发中的典型应用场景,假设我们有一个基于MVC分层结构的应用,通过controller层对外提供接口,而通过service层提供具体的实现,在service层中有一个​​WelcomeService​​​服务接口,一般情况下都是通过​​WelcomeService service = new WelcomeServiceImpl();​​创建实例并进行调用:


public class WelcomeController {
private WelcomeService service = new WelcomeServiceImpl();

@RequestMapping("/welcome")
public String welcome() {
return service.retrieveWelcomeMessage();
}
}

调用后发现一切正常,此时,功能提交,需要进行测试,而由于实际应用环境与测试环境有所区别,需要替换​​WelcomeServiceImpl​​为一个​​MockWelcomeServiceImpl​​,以方便测试,怎么办?没有其他办法,只有改代码:


public class WelcomeController {
private WelcomeService service = new MockWelcomeServiceImpl();

...
}

测试OK后再将代码改回去,这种方式太过于繁琐,且对代码的侵入性很强;
下面看通过Spring的IOC如何实现,首先将​​WelcomeService​​交由Spring管理:


<bean name="WelcomeService" class="XXX.XXX.XXX.service.impl.WelcomeServiceImpl"/>

然后在业务代码处通过Spring IOC拿到具体对象:


public class WelcomeController {
@Autowired
private WelcomeService service;

@RequestMapping("/welcome")
public String welcome() {
return service.retrieveWelcomeMessage();
}
}

测试的时候,只需要更改配置文件,将​​WelcomeService​​对应的实现改为​​MockWelcomeServiceImpl​​即可:


<bean name="WelcomeService" class="XXX.XXX.XXX.service.impl.MockWelcomeServiceImpl"/>

这种方式对业务代码没有任何侵入,它有效的实现松耦合,大家都知道紧耦合的代码是业务发展的噩梦;同时,Spring IOC提供的远不止这些,如通过单例减少创建无用的对象,通过延迟加载优化初始化成本等


当然,Spring 的核心功能远不知这些,如:

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

其实不通过Spring框架依然可以实现这些功能特定,但是Spring 提供了更优雅的抽象接口以方便对这些功能的组装,同时又给予每个具体实现以灵活的配置;另外,基于Spring,你可以方便的与其他框架进行集成,如​​hibernate​​​,​​ibatis​​等,Spring官方的原则是绝不重复造*,有好的解决方案只需要通过Spring进行集成即可。

纵览Spring的结构,你会发现Spring Framework 本身并未提供太多具体的功能,它主要专注于让你的项目代码组织更加优雅,使其具有极好的灵活性和扩展性,同时又能通过Spring集成业界优秀的解决方案

什么是Spring MVC?它解决了什么问题?

Spring MVC是Spring的一部分,Spring 出来以后,大家觉得很好用,于是按照这种模式设计了一个 MVC框架(一些用Spring 解耦的组件),主要用于开发WEB应用和网络接口,它是Spring的一个模块,通过Dispatcher Servlet, ModelAndView 和 View Resolver,让应用开发变得很容易,一个典型的Spring MVC应用开发分为下面几步:
首先通过配置文件声明Dispatcher Servlet:


<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>com.qgd.oms.web.common.mvc.OmsDispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

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

通过配置文件声明servlet详情,如MVC resource,data source,bean等


<mvc:resources mapping="/css/**/*" location="/static/css/" cache-period="21600"/>
<mvc:resources mapping="/js/**/*" location="/static/js/" cache-period="21600"/>
<mvc:resources mapping="/views/**/*.html" location="/static/views/" cache-period="21600"/>
<mvc:resources mapping="/fonts/**/*" location="/static/fonts/"/>
<mvc:resources mapping="/ueditor/**/*" location="/static/js/lib/ueditor/"/>
<mvc:resources mapping="/img/**/*" location="/static/img/"/>

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="validationQuery" value="${jdbc.validationQuery}"/>
<property name="maxTotal" value="10"/>
<property name="minIdle" value="5"/>
<property name="maxIdle" value="10"/>
<property name="defaultAutoCommit" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="true"/>
<property name="poolPreparedStatements" value="true"/>
<property name="maxOpenPreparedStatements" value="50"/>
</bean>

<bean id="configService" class="com.qgd.oms.web.common.service.ConfigService">
<property name="configStore">
<bean class="com.qgd.oms.web.common.service.impl.DbConfigStore">
<property name="dataSource" ref="dataSource"/>
<property name="taskScheduler" ref="defaultScheduler"/>
<property name="refreshInterval" value="30000"/>
</bean>
</property>
</bean>

若需添加其它功能,如security,则需添加对应配置:


<http pattern="/css/**/*" security="none"/>
<http pattern="/js/**/*" security="none"/>
<http pattern="/views/**/*.html" security="none"/>
<http pattern="/fonts/**/*" security="none"/>
<http pattern="/ueditor/**/*" security="none"/>
<http pattern="/img/**/*" security="none"/>

<http use-expressions="true" entry-point-ref="omsAuthenticationEntryPoint">
<logout logout-url="/omsmc/authentication/logout/*" success-handler-ref="omsLogoutSuccessHandler"></logout>
<intercept-url pattern='/omsmc/authentication/login*' access="permitAll" />
<intercept-url pattern='/ms/**/*' access="permitAll" />
<intercept-url pattern='/**' access="authenticated" />
<!--<security:form-login />-->
<custom-filter ref="omsUsernamePasswordAuthenticationFilter" position="FORM_LOGIN_FILTER" />
<remember-me services-ref="omsRememberMeServices" key="yfboms"/>
<csrf disabled="true"/>
</http>

增加业务代码,如controller,service,model等,最后生成war包,通过容器进行启动


什么是Spring Boot?它解决了什么问题?

初期的Spring通过代码加配置的形式为项目提供了良好的灵活性和扩展性,但随着Spring越来越庞大,其配置文件也越来越繁琐,太多复杂的xml文件也一直是Spring被人诟病的地方,特别是近些年其他简洁的WEB方案层出不穷,如基于Python或Node.Js,几行代码就能实现一个WEB服务器,对比起来,大家渐渐觉得Spring那一套太过繁琐,此时,Spring社区推出了Spring Boot,它的目的在于实现自动配置,降低项目搭建的复杂度,如需要搭建一个接口服务,通过Spring Boot,几行代码即可实现,请看代码示例:


//引入spring-boot-starter-web依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>


//声明Spring Boot应用,直接写业务逻辑即可
@Controller
@SpringBootApplication
public class MockServerApplication {
@RequestMapping("/hi")
@ResponseBody
String home() {
return "how are you!";
}

public static void main(String[] args) {
SpringApplication.run(MockServerApplication.class, args);
}
}

你甚至都不用额外的WEB容器,直接生成jar包执行即可,因为​​spring-boot-starter-web​​模块中包含有一个内置tomcat,可以直接提供容器使用;基于Spring Boot,不是说原来的配置没有了,而是Spring Boot有一套默认配置,我们可以把它看做比较通用的约定,而Spring Boot遵循的也是约定优于配置原则,同时,如果你需要使用到Spring以往提供的各种复杂但功能强大的配置功能,Spring Boot一样支持


在Spring Boot中,你会发现你引入的所有包都是starter形式,如:

  • ​spring-boot-starter-web-services​​,针对SOAP Web Services
  • ​spring-boot-starter-web​​,针对Web应用与网络接口
  • ​spring-boot-starter-jdbc​​,针对JDBC
  • ​spring-boot-starter-data-jpa​​,基于hibernate的持久层框架
  • ​spring-boot-starter-cache​​,针对缓存支持
  • 等等


这句话的译意为:

Starters是一系列及其方便的依赖描述,通过在你的项目中包含这些starter,你可以一站式获得你所需要的服务,而无需像以往那样copy各种示例配置及代码,然后调试,真正做到开箱即用;比如你想使用Spring JPA进行数据操作,只需要在你的项目依赖中引入spring-boot-starter-data-jpa即可


Spring,Spring MVC,Spring Boot 三者比较

其实写到这里,很多读者应该已经清楚,这三者专注的领域不同,解决的问题也不一样;总的来说,Spring 就像一个大家族,有众多衍生产品例如 Boot,Security,JPA等等。但他们的基础都是Spring 的 IOC 和 AOP,IOC提供了依赖注入的容器,而AOP解决了面向切面的编程,然后在此两者的基础上实现了其他衍生产品的高级功能;Spring MVC是基于 Servlet 的一个 MVC 框架,主要解决 WEB 开发的问题,因为 Spring 的配置非常复杂,各种xml,properties处理起来比较繁琐。于是为了简化开发者的使用,Spring社区创造性地推出了Spring Boot,它遵循约定优于配置,极大降低了Spring使用门槛,但又不失Spring原本灵活强大的功能,下面用一张图来描述三者的关系:

【Spring MVC和Spring Boot的关系】


总结:

Spring MVC和Spring Boot都属于Spring,Spring MVC 是基于Spring的一个 MVC 框架,而Spring Boot 是基于Spring的一套快速开发整合包