Spring Boot、Spring MVC、Spring对比
Spring Boot、Spring MVC、Spring中都有spring这个单词,让我们来看看你应该在哪儿、何时使用这些工具。
在本文,你将鸟瞰Spring、Spring MVC和Spring Boot,了解它们都处理哪些问题,它们最佳应用场景。你将认识到最重要的一点是,它们不是在同一个领域内竞争,它们都在各自的领域很出色地处理问题。
1.Spring框架处理的核心问题是什么?
好好想想,Spring框架处理的是什么问题?其实,Spring框架最核心的特性就是依赖注入(DI,Dependency Injection)。在所有的Spring模块中,最核心的部分都是依赖注入或者叫控制反转(IOC,Inversion of Control)。
为什么依赖注入和控制反转如此重要?因为,通过正确地使用依赖注入和控制反转,我们可以开发出松耦合的应用程序,然后松耦合的应用程序可以很容易地进行单元测试。
让我们来考虑一个小例子:
1.没有依赖注入的例子
考虑下面的例子:WelcomeController依赖WelcomeService去获得欢迎信息(welcome message),WelcomeController要怎么去获取WelcomeService实例呢?
@RestController
public class WelcomeController {
private WelcomeService service = new WelcomeService();
@RequestMapping("/welcome")
public String welcome() {
return service.retrieveWelcomeMessage();
}
}
上面的方式,通过WelcomeService service = new WelcomeService();
,WelcomeController创建了一个WelcomeService实例,但是它们被紧紧耦合了。例如,如果我想要对WelcomeController进行单元测试,并且mock WelcomeService,我要怎么让WelcomeController使用mock对象呢?不容易!
2.有依赖注入的例子
有依赖注入的世界简单多了,让Spring框架来做艰苦的工作。我们只需要使用两个简单的注解:@Component
和@Autowired
。
- 使用
@Component
,我们是在告诉Spring框架:嘿,这是个需要你管理的bean。 - 使用
@Autowired
,我们是在告诉Spring框架:嘿,给我找到一个最匹配这儿的类型自动装配进来。
在下面的例子中,Spring框架将为WelcomeService创建一个bean,并且自动注入到WelcomeController中。
在单元测试中,我可以要求Spring框架给WelcomeController自动装配一个WelcomeService的mock对象。(Spring Boot通过@MockBean注解让这件事情更容易,不过那又是另外一码事了。)
@Component
public class WelcomeService {
//Bla Bla Bla
}
@RestController
public class WelcomeController {
@Autowired
private WelcomeService service;
@RequestMapping("/welcome")
public String welcome() {
return service.retrieveWelcomeMessage();
}
}
2.Spring框架还处理什么问题?
问题1:重复代码、样板代码
Spring止步于依赖注入了?不,它在依赖注入的概念上构建了很多其它的Spring模块:
- Spring JDBC
- Spring MVC
- Spring AOP
- Spring ORM
- Spring JMS
- Spring Test
考虑一下Spring JMS和Spring JDBC。这些模块引入了什么新功能么?并没有!我们可以通过J2EE或者Java EE来完成这些所有工作。那么,这些模块引入了什么?它们引入简单的抽象(simple abstractions)。这些抽象的目的是:
- 减少样板代码/重复代码
- 推崇解耦合/更易于单元测试
例如,和传统的JDBC和JMS比起来,你只需要写非常少的代码来使用JDBCTemplate或者JMSTemplate。
问题2:和其它框架更好地集成
Spring框架的伟大之处在于,它没有尝试去解决已经解决的问题。它所做的是,集成一些优秀框架:
- 集成Hibernate来做ORM
- 集成iBatis(MyBatis)来做对象映射
- 集成JUnit和Mockito来做单元测试
3.Spring MVC框架主要解决什么问题?
Spring MVC框架为开发web应用提供了解耦合方式。通过简单的概念,如Dispatcher Servlet、ModelAndView和View Resolver,它使得开发web应用变得很简单。
4.我们为什么还需要Spring Boot呢?
基于Spring的应用有很多配置。当我们使用Spring MVC的时候,我们需要配置组件扫描component scan、请求分发器dispatcher servlet、一个视图解析器view resolver、web jars(用于存放静态资源)等其它事情。
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<mvc:resources mapping="/webjars/**" location="/webjars/"/>
下面的代码片段展示了web应用中配置dispatcher 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>
当我们使用Hibernate/JPA的时候,我们需要配置一个数据源datasource,一个实体类管理工厂(entity manager factory),一个事务管理器(transaction manager):
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${db.driver}" />
<property name="jdbcUrl" value="${db.url}" />
<property name="user" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:config/schema.sql" />
<jdbc:script location="classpath:config/data.sql" />
</jdbc:initialize-database>
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="persistenceUnitName" value="hsql_pu" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
问题#1.Spring Boot自动配置:我们可以从不同的角度思考么?
Spring Boot提供了一种新的思考方式:我们可以引入更多的智慧嘛?当spring mvc的jar被添加进入应用,我们不能自动配置一些bean嘛?
- 如果Hibernate jar在classpath下,怎么自动配置一个DataSource?
- 如果Spring MVC jar在classpath下,怎么自动配置一个DispatcherServlet?
还应该提供一种可以覆盖自动配置的方式。
Spring Boot通过查看
a)classpath下的可用的框架
b)应用已有的配置
来提供一些需要为集成了这些框架的应用
提供一些基础配置,也叫做Auto Configuration(自动配置)。
问题#2.Spring Boot起步工程:建立在众所周知的模式上
比如我们需要开发一个web应用。
首先,我们需要明确我们想使用什么框架,使用哪个版本的框架,怎么将它们连接在一起。
所有的web应用都有类似的需求。下面列举了一些在Spring MVC中会使用到的依赖:
<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 MVC,Jackson Databind,Hibernate-Validator和Log4j。当开发Spring MVC应用的时候,我们需要选择这些框架的兼容版本。
下面是Spring Boot官方文档关于starters(起步依赖)的描述:
Starters是一系列可以在应用中很方便地使用的依赖描述。你可以获得你需要的所有Spring及其相关的技术的一站式服务,不需要去寻找、拷贝别的工程的依赖。例如,如果你想使用Spring和JPA来做数据访问,只需要在项目中引入spring-boot-starter-data-jpa
依赖即可。
让我们看看一个起步依赖的例子:Spring Boot Starter Web。
如果你想要开发一个web应用,或者一个需要暴露restful服务的应用,Spring Boot Starter Web可以拿来用用。我们可以通过使用Spring Initializer来快速创建一个使用了Spring Boot Starter Web的工程。
Spring Boot Starter Web依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
然后你可以在你的应用的依赖中看到:
依赖可以被分类为:
- Spring: core, beans, context, aop
- Web MVC: (Spring MVC)
- Jackson: for JSON Binding
- Validation: Hibernate Validator, Validation API
- Embedded Servlet Container: Tomcat
- Logging: logback, slf4j
任何典型的web应用都将使用这些依赖。Spring Boot Starter Web提前把它们打包好了。作为一个开发者,你不用再担心它们之间会有版本冲突了。
Spring Boot Starter项目可选列表:
从Spring Boot Starter Web项目中可以看到,starter工程让我们开发特定类型的应用更快速。还有如下的starter工程可供选择:
- spring-boot-starter-web-services: SOAP Web Services
- spring-boot-starter-web: Web and RESTful applications
- spring-boot-starter-test: Unit testing and Integration Testing
- spring-boot-starter-jdbc: Traditional JDBC
- spring-boot-starter-hateoas: Add HATEOAS features to your services
- spring-boot-starter-security: Authentication and Authorization using Spring Security
- spring-boot-starter-data-jpa: Spring Data JPA with Hibernate
- spring-boot-starter-cache: Enabling Spring Framework’s caching support
- spring-boot-starter-data-rest: Expose Simple REST Services using Spring Data REST
Spring Boot的其它目标
还有一些技术性的starter:
- spring-boot-starter-actuator: 开箱即用的高级特性,用于监控和追踪你的应用。
- spring-boot-starter-undertow, spring-boot-starter-jetty, spring-boot-starter-tomcat: 让你选择自己特定的内嵌Servlet容器。
- spring-boot-starter-logging: 用于使用logback记录日志。
- spring-boot-starter-log4j2: 用于使用Log4j2记录日志。
原文链接:https://dzone.com/articles/spring-boot-vs-spring-mvc-vs-spring-how-do-they-compare