為什么是Spring Boot

原文: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 注解和 PropertySourcesPlaceholderConfigurer Bean 定義配置 PropertyPlaceHolder bean 從 application.properties 文件加載配置
  • DataSource、JAP 的 EntityManagerFactoryJpaTransactionManager 定義 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、EntityManagerFactoryTransactionManager 等 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.javaHomeController.java。

步驟 4、創(chuàng)建用于顯示用戶列表的 Thymeleaf 視圖

springmvc-jpa-demo 項目中復(fù)制之前創(chuàng)建的 /WEB-INF/views/index.htmlsrc/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ā)生的事情。

  1. 簡單的依賴管理

    • 首先要注意的是我們使用了一些名為 spring-boot-start-* 的依賴。記住我說過我花費 95% 的時間來配置同樣的配置。當(dāng)你在開發(fā) Spring MVC 應(yīng)用時添加了 spring-boot-start-web 依賴,它已經(jīng)包含了一些常用的類庫,比如 spring-webmvcjackson-json、validation-apitomcat 等。

    • 我們添加了 spring-boot-starter-data-jpa 依賴。它包含了所有的 spring-data-jpa 依賴,并且還添加了 Hibernate 庫,因為很多應(yīng)用使用 Hibernate 作為 JPA 實現(xiàn)。

  2. 自動配置

    • spring-boot-starter-web 不僅添加了上面所說的這些庫,還配置了經(jīng)常被注冊的 bean,比如 DispatcherServlet、ResourceHandlerMessageSource 等 bean,并且應(yīng)用了合適的默認(rèn)配置。

    • 我們還添加了 spring-boot-starter-Thymeleaf,它不僅添加了 Thymeleaf 的依賴,還自動配置了 ThymeleafViewResolver bean。

    • 雖然我們沒有定義任何 DataSource、EntityManagerFactoryTransactionManager 等 bean,但它們可以被自動創(chuàng)建。怎么樣?如果在 classpath 下沒有任何內(nèi)存數(shù)據(jù)庫驅(qū)動,如 H2 或者 HSQL,那么 Spring Boot 將自動創(chuàng)建一個內(nèi)存數(shù)據(jù)庫的 DataSource,然后應(yīng)用合適的默認(rèn)配置自動注冊 EntityManagerFactoryTransactionManager 等 bean。但是我們使用的是 MySQL,因此我們需要明確提供 MySQL 的連接信息。我們已經(jīng)在 application.properties 文件中配置了 MySQL 連接信息,Spring Boot 將應(yīng)用這些配置來創(chuàng)建 DataSource

  3. 支持嵌入式 Servlet 容器

    • 最重要且最讓人驚訝的是,我們創(chuàng)建了一個簡單的 Java 類,標(biāo)記了一個神奇的注解 @SpringApplication,它有一個 main 方法。通過運行 main 方法,我們可以啟動這個應(yīng)用,并可通過 http://localhost:8080/ 來訪問。

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,了解它的工作原理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,261評論 6 342
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,534評論 19 139
  • 此篇翻譯的是Spring Boot官方指南 Part III. 使用 Spring Boot (Using Spr...
    K天道酬勤閱讀 6,942評論 0 21
  • 絲念 [詩第122首] 文\戀風(fēng) 月光下 蜘蛛 悄悄地織起一根根的絲念 獨自刷屏了整個網(wǎng) 它 寂寞的守在網(wǎng)中間 看...
    戀風(fēng)2016閱讀 325評論 1 1
  • 寂寞是夜里的寒星 , 你披上衣衫, 舉首遙望 , 天空蔓延出嬌喘的黎明 。 寂寞是案前的孤燈 , 你奮筆疾書 , ...
    A欣欣向榮閱讀 411評論 0 0

友情鏈接更多精彩內(nèi)容