原文:https://dzone.com/articles/why-springboot
作者:Siva Prasad Reddy Katamreddy
譯者:Oopsguy
本文將介紹各種 Spring 的配置方式,幫助你了解配置 Spring 應(yīng)用的復(fù)雜性。
Spring 是一個非常受歡迎的 Java 框架,它用于構(gòu)建 Web 和企業(yè)應(yīng)用。不像許多其他框架只關(guān)注一個領(lǐng)域,Spring 框架提供了各種功能,通過項目組合來滿足當(dāng)代業(yè)務(wù)需求。
Spring 框架提供了多種靈活的方式來配置 Bean。例如 XML、注解和 Java 配置。隨著功能數(shù)量的增加,復(fù)雜性也隨之增加,配置 Spring 應(yīng)用將變得乏味且容易出錯。
針對上述問題,Spring 團隊創(chuàng)建了 Spring Boot 以解決配置復(fù)雜的問題。
但在開始將 Spring Boot 之前,我們將快速瀏覽一下 Spring 框架,看看 Spring Boot 正在決解什么樣的問題。
在本文中,我們將介紹:
- Spring 框架概述
- 一個使用了 Spring MVC 和 JPA(Hibernate)的 Web 應(yīng)用
- 快速嘗試 Spring Boot
Spring 框架概述
如果你是一名 Java 開發(fā)人員,那你很可能聽說過 Spring 框架,甚至可能已經(jīng)在自己的項目中使用了它。Spring 框架主要是作為依賴注入容器,但它的作用遠不止這些。
Spring 很受歡迎的原因有幾點:
- Spring 的依賴注入方式鼓勵編寫可測試的代碼
- 具備簡單但功能強大的數(shù)據(jù)庫事務(wù)管理功能
- Spring 簡化了與其他 Java 框架的集成工作,比如 JPA/Hibernate ORM 和 Struts/JSF 等 Web 框架
- 構(gòu)建 Web 應(yīng)用最先進的 Web MVC 框架。
連同 Spring 一起的,還有許多其他的 Spring 姊妹項目,可以幫助構(gòu)建滿足當(dāng)代業(yè)務(wù)需求的應(yīng)用:
- Spring Data:簡化關(guān)系數(shù)據(jù)庫和 NoSQL 數(shù)據(jù)存儲的數(shù)據(jù)訪問
- Spring Batch:提供強大的批處理能力
- Spring Security:用于保護應(yīng)用安全框架
- Spring Social:支持與 Facebook、Twitter、Linkedin、Github 等社交網(wǎng)站集成
- Spring Integration:實現(xiàn)了企業(yè)集成模式,以便于使用輕量級消息和聲明式適配器與其他企業(yè)應(yīng)用集成
還有許多其他有趣的項目涉及各種其他當(dāng)代應(yīng)用開發(fā)需求。有關(guān)更多信息,請查看 http://spring.io/projects。
剛開始,Spring 框架只提供了基于 XML 的方式來配置 bean。后來,Spring 引入了基于 XML 的 DSL、注解和基于 Java 配置的方式來配置 bean。
讓我們快速了解一下這些配置風(fēng)格的大概模樣。
基于 XML 的配置
<bean id="userService" class="com.sivalabs.myapp.service.UserService">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.sivalabs.myapp.dao.JdbcUserDao">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="secret"/>
</bean>
基于注解的配置
@Service
public class UserService
{
private UserDao userDao;
@Autowired
public UserService(UserDao dao){
this.userDao = dao;
}
...
...
}
@Repository
public class JdbcUserDao
{
private DataSource dataSource;
@Autowired
public JdbcUserDao(DataSource dataSource){
this.dataSource = dataSource;
}
...
...
}
基于 Java 代碼的配置
@Configuration
public class AppConfig
{
@Bean
public UserService userService(UserDao dao){
return new UserService(dao);
}
@Bean
public UserDao userDao(DataSource dataSource){
return new JdbcUserDao(dataSource);
}
@Bean
public DataSource dataSource(){
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("secret");
return dataSource;
}
}
Spring 提供了多種方式來做同樣的事,我們甚至可以混合使用,在同一個應(yīng)用中使用基于 Java 配置和注解配置的方式。
這非常靈活,但它有好有壞。剛開始接觸 Spring 的新人可能會困惑應(yīng)該使用哪一種方式。到目前為止,Spring 團隊建議使用基于 Java 配置的方式,因為它更具靈活性。
沒有哪一種方案是萬能,我們應(yīng)該根據(jù)自己的需求來選擇合適的方式。
到此,你已經(jīng)了解了多種 Spring Bean 配置方式的基本形式。
讓我們快速地了解一下典型的 Spring MVC+JPA/Hibernate Web 應(yīng)用的配置。
一個使用了 Spring MVC 和 JPA(Hibernate)的 Web 應(yīng)用
在了解 Spring Boot 是什么以及它提供了什么樣的功能之前,我們先來看一下典型的 Spring Web 應(yīng)用配置是怎樣的,哪些是痛點,然后我們將討論 Spring Boot 是如何解決這些問題的。
步驟 1、配置 Maven 依賴
首先需要做的是配置 pom.xml 中所需的依賴:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sivalabs</groupId>
<artifactId>springmvc-jpa-demo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>springmvc-jpa-demo</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.190</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.11.Final</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
</dependencies>
</project>
我們配置了所有的 Maven jar 依賴,包括 Spring MVC、Spring Data JPA、JPA/Hibernate、Thymeleaf 和 Log4j。
步驟 2、使用 Java 配置配置 Service/DAO 層的 Bean
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="com.sivalabs.demo")
@PropertySource(value = { "classpath:application.properties" })
public class AppConfig
{
@Autowired
private Environment env;
@Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer()
{
return new PropertySourcesPlaceholderConfigurer();
}
@Value("${init-db:false}")
private String initDatabase;
@Bean
public PlatformTransactionManager transactionManager()
{
EntityManagerFactory factory = entityManagerFactory().getObject();
return new JpaTransactionManager(factory);
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory()
{
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(Boolean.TRUE);
vendorAdapter.setShowSql(Boolean.TRUE);
factory.setDataSource(dataSource());
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.sivalabs.demo");
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
factory.setJpaProperties(jpaProperties);
factory.afterPropertiesSet();
factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
return factory;
}
@Bean
public HibernateExceptionTranslator hibernateExceptionTranslator()
{
return new HibernateExceptionTranslator();
}
@Bean
public DataSource dataSource()
{
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.username"));
dataSource.setPassword(env.getProperty("jdbc.password"));
return dataSource;
}
@Bean
public DataSourceInitializer dataSourceInitializer(DataSource dataSource)
{
DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
dataSourceInitializer.setDataSource(dataSource);
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
databasePopulator.addScript(new ClassPathResource("data.sql"));
dataSourceInitializer.setDatabasePopulator(databasePopulator);
dataSourceInitializer.setEnabled(Boolean.parseBoolean(initDatabase));
return dataSourceInitializer;
}
}
在 AppConfig.java 配置類中,我們完成了以下操作:
- 使用
@Configuration注解標(biāo)記為一個 Spring 配置類 - 使用
@EnableTransactionManagement開啟基于注解的事務(wù)管理 - 配置
@EnableJpaRepositories指定去哪查找 Spring Data JPA 資源庫(repository) - 使用
@PropertySource注解和PropertySourcesPlaceholderConfigurerBean 定義配置PropertyPlaceHolderbean 從application.properties文件加載配置 - 為 DataSource、JAP 的 EntityManagerFactory 和 JpaTransactionManager 定義 Bean
- 配置 DataSourceInitializer Bean,在應(yīng)用啟動時,執(zhí)行
data.sql腳本來初始化數(shù)據(jù)庫
我們需要在 application.properties 中完善配置,如下所示:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=admin
init-db=true
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
我們可以創(chuàng)建一個簡單的 SQL 腳本 data.sql 來將演示數(shù)據(jù)填充到 USER 表中:
delete from user;
insert into user(id, name) values(1,'Siva');
insert into user(id, name) values(2,'Prasad');
insert into user(id, name) values(3,'Reddy');
我們可以創(chuàng)建一個附帶基本配置的 log4j.properties 文件,如下所示:
log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %t %c{2}:%L - %m%n
log4j.category.org.springframework=INFO
log4j.category.com.sivalabs=DEBUG
步驟 3、配置 Spring MVC Web 層的 Bean
我們必須配置 Thymleaf 的 ViewResolver、處理靜態(tài)資源的 ResourceHandler 和處理 I18n 的 MessageSource 等。
@Configuration
@ComponentScan(basePackages = { "com.sivalabs.demo"})
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter
{
@Bean
public TemplateResolver templateResolver() {
TemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCacheable(false);
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
@Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
thymeleafViewResolver.setTemplateEngine(templateEngine());
thymeleafViewResolver.setCharacterEncoding("UTF-8");
return thymeleafViewResolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
{
configurer.enable();
}
@Bean(name = "messageSource")
public MessageSource configureMessageSource()
{
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setCacheSeconds(5);
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
}
在 WebMvcConfig.java 配置類中,我們完成了以下操作:
- 使用
@Configuration注解標(biāo)記為一個 Spring 配置類 - 使用
@EnableWebMvc注解啟用基于注解的 Spring MVC 配置 - 通過注冊 TemplateResolver、SpringTemplateEngine 和 `hymeleafViewResolver Bean 來配置 Thymeleaf 視圖解析器
- 注冊 ResourceHandler Bean 將 URI 為
/resource/**的靜態(tài)資源請求定位到/resource/目錄下 - 配置 MessageSource Bean 從 classpath 中加載 messages-{國家代碼}.properties 文件來加載 I18n 配置
現(xiàn)在我們沒有配置任何 I18n 內(nèi)容,因此需要在 src/main/resources 文件夾下創(chuàng)建一個空的 messages.properties 文件。
步驟 4、注冊 Spring MVC 的前端控制器 DispatcherServlet
在 Servlet 3.x 規(guī)范之前,我們必須在 web.xml 中注冊 Servlet/Filter。由于當(dāng)前是 Servlet 3.x 環(huán)境,我們可以使用 ServletContainerInitializer 以編程的方式注冊 Servlet/Filter。
Spring MVC 提供了一個慣例類 AbstractAnnotationConfigDispatcherServletInitializer 來注冊 DispatcherServlet。
public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class<?>[] { AppConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return new Class<?>[] { WebMvcConfig.class };
}
@Override
protected String[] getServletMappings()
{
return new String[] { "/" };
}
@Override
protected Filter[] getServletFilters() {
return new Filter[]{ new OpenEntityManagerInViewFilter() };
}
}
在 SpringWebAppInitializer.java 配置類中,我們完成了以下操作:
- 我們將
AppConfig.class配置為 RootConfigurationClass,它將成為包含所有子上下文(DispatcherServlet)共享的 Bean 定義的父 ApplicationContext - 我們將
WebMvcConfig.class配置為 ServletConfigClass,它是包含了 WebMvc Bean 定義的子 ApplicationContext - 我們將
/配置為 ServletMapping,這意味所有的請求將由 DispatcherServlet 處理 - 我們將 OpenEntityManagerInViewFilter 注冊為 Servlet 過濾器,以便在渲染視圖時可以延遲加載 JPA Entity 的延遲集合
步驟 5、創(chuàng)建一個 JPA 實體和 Spring Data JPA 資源庫
為 User 實體創(chuàng)建一個 JPA 實體 User.java 和一個 Spring Data JPA 資源庫。
@Entity
public class User
{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
//setters and getters
}
public interface UserRepository extends JpaRepository<User, Integer>
{
}
步驟 6、創(chuàng)建一個 Spring MVC 控制器
創(chuàng)建一個 Spring MVC 控制器來處理 URL 為 /,并渲染一個用戶列表。
@Controller
public class HomeController
{
@Autowired UserRepository userRepo;
@RequestMapping("/")
public String home(Model model)
{
model.addAttribute("users", userRepo.findAll());
return "index";
}
}
步驟 7、創(chuàng)建一個 Thymeleaf 視圖 /WEB-INF/views/index.html 來渲染用戶列表
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8"/>
<title>Home</title>
</head>
<body>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${users}">
<td th:text="${user.id}">Id</td>
<td th:text="${user.name}">Name</td>
</tr>
</tbody>
</table>
</body>
</html>
所有都配置好了,可以啟動應(yīng)用了。但在此之前,我們需要在 IDE 中下載并配置像 Tomcat、Jetty 或者 Wildfly 等服務(wù)器。
你可以下載 Tomcat 8 并配置在你喜歡的 IDE 中,之后運行應(yīng)用并將瀏覽器指向 http://localhost:8080/springmvc-jpa-demo。你應(yīng)該看到一個以表格形式展示的用戶詳細(xì)信息列表。
真激動,我們做到了!
但是等等,做了那么多的工作僅僅是為了從數(shù)據(jù)庫中獲取用戶信息然后展示一個列表?
讓我們坦誠公平地來看待,所有的這些配置不僅僅是為了這次示例,這些配置也是其他應(yīng)用的基礎(chǔ)。
但我還是想說,如果你想早點起床跑步,那對不起,你還有太多的工作要做。
另一個問題是,假設(shè)你想要開發(fā)另一個 Spring MVC 應(yīng)用,你會使用類似的技術(shù)棧?
好,你要做的就是復(fù)制粘貼配置并調(diào)整它。對么?請記住一件事:如果你一次又一次地做同樣的事情,你應(yīng)該尋找一種自動化的方式來完成它。
除了一遍又一遍地編寫相同的配置,你還能發(fā)現(xiàn)其他問題么?
這樣吧,讓我列出我從中發(fā)現(xiàn)的問題。
- 你需要尋找特定版本的 Spring 以便完全兼容所有的類庫,并進行配置。
- 我們花費了 95% 的時間以同樣的方式配置 DataSource、EntityManagerFactory 和 TransactionManager 等 bean。如果 Spring 能自動幫我們完成這些事,是不是非常棒?
- 同樣,我們大多時候以同樣的方式配置 Spring MVC 的 bean,比如 ViewResolver、MessageResource 等。
如果 Spring 可以自動幫我做這些事情,那真的是非!常!棒!
想象一下,如果 Spring 能夠自動配置 bean 呢?如果你可以使用簡單的自定義配置方式來定義自動配置又將會怎么?
例如,你可以將 DispatcherServlet 的 url-pattern 映射到 /app/,而不是 /。你可以將 Theymeleaf 視圖放在 /WEB-INF/template/ 文件夾下,而不是 /WEB-INF/views 中。
所以基本上你希望 Spring 能自動執(zhí)行這些操作,Spring 它有沒有提供一個簡單靈活的方式來覆蓋掉默認(rèn)配置呢?
很好,你即將踏進入 Spring Boot 的世界,你將夢想成真!
快速嘗試 Spring Boot
歡迎來到 Spring Boot 世界!Spring Boot 正是你一直在尋找的。它可以自動為你完成某些事情,但如果有必要,你可以覆蓋掉這些默認(rèn)配置。
與其夸夸而談,不如來點案例實戰(zhàn)。
步驟 1、創(chuàng)建一個基于 Maven 的 Spring Boot 應(yīng)用
創(chuàng)建一個 Maven 項目并配置如下依賴:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sivalabs</groupId>
<artifactId>hello-springboot</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>hello-springboot</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
</project>
太神奇了,我們的 pom.xml 文件一下子變小了許多!
步驟 2、如下在 application.properties 中配置 DataSoure/JPA
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.initialize=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
你可以將相同的 data.sql 文件拷貝到 src/main/resources 文件加中。
步驟 3、為實體創(chuàng)建一個 JPA 實體和 Spring Data JPA 資源庫接口
與 springmvc-jpa-demo 應(yīng)用一樣,創(chuàng)建 User.java、UserRepository.java 和 HomeController.java。
步驟 4、創(chuàng)建用于顯示用戶列表的 Thymeleaf 視圖
從 springmvc-jpa-demo 項目中復(fù)制之前創(chuàng)建的 /WEB-INF/views/index.html 到 src/main/resources/template 文件夾中。
步驟 5、創(chuàng)建 Spring Boot 入口類
創(chuàng)建一個含有 main 方法的 Java 類 Application.java,如下所示:
@SpringBootApplication
public class Application
{
public static void main(String[] args)
{
SpringApplication.run(Application.class, args);
}
}
現(xiàn)在把 Application.java 當(dāng)作一個 Java 應(yīng)用運行,并將你的瀏覽其指向 http://localhost:8080/。
不出意外,你將看到一個以表格的形式展示的用戶列表,真的很酷!
我仿佛聽到你在喊:“這到底發(fā)生了什么事?”。
讓我解釋剛剛所發(fā)生的事情。
-
簡單的依賴管理
首先要注意的是我們使用了一些名為
spring-boot-start-*的依賴。記住我說過我花費 95% 的時間來配置同樣的配置。當(dāng)你在開發(fā) Spring MVC 應(yīng)用時添加了spring-boot-start-web依賴,它已經(jīng)包含了一些常用的類庫,比如 spring-webmvc、jackson-json、validation-api 和 tomcat 等。我們添加了
spring-boot-starter-data-jpa依賴。它包含了所有的spring-data-jpa依賴,并且還添加了 Hibernate 庫,因為很多應(yīng)用使用 Hibernate 作為 JPA 實現(xiàn)。
-
自動配置
spring-boot-starter-web不僅添加了上面所說的這些庫,還配置了經(jīng)常被注冊的 bean,比如 DispatcherServlet、ResourceHandler 和 MessageSource 等 bean,并且應(yīng)用了合適的默認(rèn)配置。我們還添加了
spring-boot-starter-Thymeleaf,它不僅添加了 Thymeleaf 的依賴,還自動配置了 ThymeleafViewResolver bean。雖然我們沒有定義任何 DataSource、EntityManagerFactory 和 TransactionManager 等 bean,但它們可以被自動創(chuàng)建。怎么樣?如果在 classpath 下沒有任何內(nèi)存數(shù)據(jù)庫驅(qū)動,如 H2 或者 HSQL,那么 Spring Boot 將自動創(chuàng)建一個內(nèi)存數(shù)據(jù)庫的 DataSource,然后應(yīng)用合適的默認(rèn)配置自動注冊 EntityManagerFactory 和 TransactionManager 等 bean。但是我們使用的是 MySQL,因此我們需要明確提供 MySQL 的連接信息。我們已經(jīng)在
application.properties文件中配置了 MySQL 連接信息,Spring Boot 將應(yīng)用這些配置來創(chuàng)建 DataSource。
-
支持嵌入式 Servlet 容器
- 最重要且最讓人驚訝的是,我們創(chuàng)建了一個簡單的 Java 類,標(biāo)記了一個神奇的注解
@SpringApplication,它有一個main方法。通過運行main方法,我們可以啟動這個應(yīng)用,并可通過http://localhost:8080/來訪問。
- 最重要且最讓人驚訝的是,我們創(chuàng)建了一個簡單的 Java 類,標(biāo)記了一個神奇的注解
Servlet 容器來自哪里?
我們添加了 spring-boot-starter-web,它會自動引入 spring-boot-starter-tomcat。當(dāng)我們運行 main() 方法時,它將 tomcat 作為一個嵌入式容器啟動,我們不需要部署自己的應(yīng)用到外部安裝好的 tomcat 上。
順便說一句,你看到我們在 pom.xml 中配置的打包類型是 jar 而不是 war,真有趣!
非常好,但如果我想使用 jetty 服務(wù)器而不是 tomcat 呢?很簡單,只需要從 spring-boot-starter-web 中排除掉 sprig-boot-starter-tomcat,并包含 spring-boot-starter-jetty 依賴即可。
就是這樣。
但這看起來真的很神奇!
我可以想象此時你在想什么。你正在感嘆 Spring Boot 真的很酷,它為你自動完成了很多事情。但是,你還沒了完全明白它幕后是怎樣工作的,對不對?
我可以理解,就像觀看魔術(shù)表演,過程非常有趣,但你不知道魔術(shù)師是如何做到的。軟件開發(fā)則不一樣,你不用擔(dān)心,未來我們還將看到各種新奇的東西,并在以后的文章中詳細(xì)地解釋它們幕后的工作原理。很遺憾的是,我不能在這篇文章中把所有的東西都教給你。
總結(jié)
在本文中,我們快速介紹了 Spring 的各種配置風(fēng)格,并了解了配置 Spring 應(yīng)用的復(fù)雜性。此外,我們通過創(chuàng)建一個簡單的 Web 應(yīng)用來快速了解 Spring Boot。
在下一篇文章中,我們將深入了解 Spring Boot,了解它的工作原理。