為什么是Spring Boot

原文:https://dzone.com/articles/why-springboot
作者:Siva Prasad Reddy Katamreddy
譯者:Oopsguy

本文將介紹各種 Spring 的配置方式,幫助你了解配置 Spring 應(yīng)用的復(fù)雜性。

Spring 是一個(gè)非常受歡迎的 Java 框架缀皱,它用于構(gòu)建 Web 和企業(yè)應(yīng)用。不像許多其他框架只關(guān)注一個(gè)領(lǐng)域复颈,Spring 框架提供了各種功能舟扎,通過項(xiàng)目組合來滿足當(dāng)代業(yè)務(wù)需求几蜻。

Spring 框架提供了多種靈活的方式來配置 Bean寞冯。例如 XML注解Java 配置猜欺。隨著功能數(shù)量的增加位隶,復(fù)雜性也隨之增加,配置 Spring 應(yīng)用將變得乏味且容易出錯(cuò)开皿。

針對(duì)上述問題涧黄,Spring 團(tuán)隊(duì)創(chuàng)建了 Spring Boot 以解決配置復(fù)雜的問題。

但在開始將 Spring Boot 之前赋荆,我們將快速瀏覽一下 Spring 框架笋妥,看看 Spring Boot 正在決解什么樣的問題。

在本文中窄潭,我們將介紹:

  • Spring 框架概述
  • 一個(gè)使用了 Spring MVC 和 JPA(Hibernate)的 Web 應(yīng)用
  • 快速嘗試 Spring Boot

Spring 框架概述

如果你是一名 Java 開發(fā)人員春宣,那你很可能聽說過 Spring 框架,甚至可能已經(jīng)在自己的項(xiàng)目中使用了它狈孔。Spring 框架主要是作為依賴注入容器信认,但它的作用遠(yuǎn)不止這些。

Spring 很受歡迎的原因有幾點(diǎn):

  • Spring 的依賴注入方式鼓勵(lì)編寫可測(cè)試的代碼
  • 具備簡(jiǎn)單但功能強(qiáng)大的數(shù)據(jù)庫(kù)事務(wù)管理功能
  • Spring 簡(jiǎn)化了與其他 Java 框架的集成工作均抽,比如 JPA/Hibernate ORM 和 Struts/JSF 等 Web 框架
  • 構(gòu)建 Web 應(yīng)用最先進(jìn)的 Web MVC 框架嫁赏。

連同 Spring 一起的,還有許多其他的 Spring 姊妹項(xiàng)目油挥,可以幫助構(gòu)建滿足當(dāng)代業(yè)務(wù)需求的應(yīng)用:

  • Spring Data:簡(jiǎn)化關(guān)系數(shù)據(jù)庫(kù)和 NoSQL 數(shù)據(jù)存儲(chǔ)的數(shù)據(jù)訪問
  • Spring Batch:提供強(qiáng)大的批處理能力
  • Spring Security:用于保護(hù)應(yīng)用安全框架
  • Spring Social:支持與 Facebook潦蝇、Twitter、Linkedin深寥、Github 等社交網(wǎng)站集成
  • Spring Integration:實(shí)現(xiàn)了企業(yè)集成模式攘乒,以便于使用輕量級(jí)消息和聲明式適配器與其他企業(yè)應(yīng)用集成

還有許多其他有趣的項(xiàng)目涉及各種其他當(dāng)代應(yīng)用開發(fā)需求。有關(guān)更多信息惋鹅,請(qǐng)查看 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 提供了多種方式來做同樣的事,我們甚至可以混合使用沐鼠,在同一個(gè)應(yīng)用中使用基于 Java 配置和注解配置的方式挚瘟。

這非常靈活叹谁,但它有好有壞。剛開始接觸 Spring 的新人可能會(huì)困惑應(yīng)該使用哪一種方式乘盖。到目前為止焰檩,Spring 團(tuán)隊(duì)建議使用基于 Java 配置的方式,因?yàn)樗哽`活性侧漓。

沒有哪一種方案是萬能锅尘,我們應(yīng)該根據(jù)自己的需求來選擇合適的方式监氢。

到此布蔗,你已經(jīng)了解了多種 Spring Bean 配置方式的基本形式。

讓我們快速地了解一下典型的 Spring MVC+JPA/Hibernate Web 應(yīng)用的配置浪腐。

一個(gè)使用了 Spring MVC 和 JPA(Hibernate)的 Web 應(yīng)用

在了解 Spring Boot 是什么以及它提供了什么樣的功能之前纵揍,我們先來看一下典型的 Spring Web 應(yīng)用配置是怎樣的,哪些是痛點(diǎn)议街,然后我們將討論 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)記為一個(gè) Spring 配置類
  • 使用 @EnableTransactionManagement 開啟基于注解的事務(wù)管理
  • 配置 @EnableJpaRepositories 指定去哪查找 Spring Data JPA 資源庫(kù)(repository)
  • 使用 @PropertySource 注解和 PropertySourcesPlaceholderConfigurer Bean 定義配置 PropertyPlaceHolder bean 從 application.properties 文件加載配置
  • DataSource丁鹉、JAP 的 EntityManagerFactoryJpaTransactionManager 定義 Bean
  • 配置 DataSourceInitializer Bean,在應(yīng)用啟動(dòng)時(shí)悴能,執(zhí)行 data.sql 腳本來初始化數(shù)據(jù)庫(kù)

我們需要在 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)建一個(gè)簡(jiǎn)單的 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)建一個(gè)附帶基本配置的 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)記為一個(gè) Spring 配置類
  • 使用 @EnableWebMvc 注解啟用基于注解的 Spring MVC 配置
  • 通過注冊(cè) TemplateResolver宇姚、SpringTemplateEngine 和 `hymeleafViewResolver Bean 來配置 Thymeleaf 視圖解析器
  • 注冊(cè) ResourceHandler Bean 將 URI 為 /resource/** 的靜態(tài)資源請(qǐng)求定位到 /resource/ 目錄下
  • 配置 MessageSource Bean 從 classpath 中加載 messages-{國(guó)家代碼}.properties 文件來加載 I18n 配置

現(xiàn)在我們沒有配置任何 I18n 內(nèi)容,因此需要在 src/main/resources 文件夾下創(chuàng)建一個(gè)空的 messages.properties 文件摸吠。

步驟 4空凸、注冊(cè) Spring MVC 的前端控制器 DispatcherServlet

在 Servlet 3.x 規(guī)范之前,我們必須在 web.xml 中注冊(cè) Servlet/Filter寸痢。由于當(dāng)前是 Servlet 3.x 環(huán)境呀洲,我們可以使用 ServletContainerInitializer 以編程的方式注冊(cè) Servlet/Filter。

Spring MVC 提供了一個(gè)慣例類 AbstractAnnotationConfigDispatcherServletInitializer 來注冊(cè) 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滓窍,這意味所有的請(qǐng)求將由 DispatcherServlet 處理
  • 我們將 OpenEntityManagerInViewFilter 注冊(cè)為 Servlet 過濾器卖词,以便在渲染視圖時(shí)可以延遲加載 JPA Entity 的延遲集合

步驟 5、創(chuàng)建一個(gè) JPA 實(shí)體和 Spring Data JPA 資源庫(kù)

為 User 實(shí)體創(chuàng)建一個(gè) JPA 實(shí)體 User.java 和一個(gè) Spring Data JPA 資源庫(kù)吏夯。

@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)建一個(gè) Spring MVC 控制器

創(chuàng)建一個(gè) Spring MVC 控制器來處理 URL 為 /,并渲染一個(gè)用戶列表噪生。

@Controller
public class HomeController
{
    @Autowired UserRepository userRepo;
    @RequestMapping("/")
    public String home(Model model)
    {
        model.addAttribute("users", userRepo.findAll());
        return "index";
    }
}

步驟 7裆赵、創(chuàng)建一個(gè) 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>

所有都配置好了,可以啟動(dòng)應(yīng)用了跺嗽。但在此之前战授,我們需要在 IDE 中下載并配置像 TomcatJetty 或者 Wildfly 等服務(wù)器桨嫁。

你可以下載 Tomcat 8 并配置在你喜歡的 IDE 中植兰,之后運(yùn)行應(yīng)用并將瀏覽器指向 http://localhost:8080/springmvc-jpa-demo。你應(yīng)該看到一個(gè)以表格形式展示的用戶詳細(xì)信息列表璃吧。

真激動(dòng)楣导,我們做到了!

但是等等肚逸,做了那么多的工作僅僅是為了從數(shù)據(jù)庫(kù)中獲取用戶信息然后展示一個(gè)列表爷辙?

讓我們坦誠(chéng)公平地來看待,所有的這些配置不僅僅是為了這次示例朦促,這些配置也是其他應(yīng)用的基礎(chǔ)膝晾。

但我還是想說,如果你想早點(diǎn)起床跑步务冕,那對(duì)不起血当,你還有太多的工作要做。

另一個(gè)問題是禀忆,假設(shè)你想要開發(fā)另一個(gè) Spring MVC 應(yīng)用臊旭,你會(huì)使用類似的技術(shù)棧?

好箩退,你要做的就是復(fù)制粘貼配置并調(diào)整它离熏。對(duì)么?請(qǐng)記住一件事:如果你一次又一次地做同樣的事情戴涝,你應(yīng)該尋找一種自動(dòng)化的方式來完成它滋戳。

除了一遍又一遍地編寫相同的配置钻蔑,你還能發(fā)現(xiàn)其他問題么?

這樣吧奸鸯,讓我列出我從中發(fā)現(xiàn)的問題咪笑。

  • 你需要尋找特定版本的 Spring 以便完全兼容所有的類庫(kù),并進(jìn)行配置娄涩。
  • 我們花費(fèi)了 95% 的時(shí)間以同樣的方式配置 DataSource窗怒、EntityManagerFactoryTransactionManager 等 bean。如果 Spring 能自動(dòng)幫我們完成這些事蓄拣,是不是非常棒扬虚?
  • 同樣,我們大多時(shí)候以同樣的方式配置 Spring MVC 的 bean弯蚜,比如 ViewResolver孔轴、MessageResource 等剃法。

如果 Spring 可以自動(dòng)幫我做這些事情碎捺,那真的是非!常贷洲!棒收厨!

想象一下,如果 Spring 能夠自動(dòng)配置 bean 呢优构?如果你可以使用簡(jiǎn)單的自定義配置方式來定義自動(dòng)配置又將會(huì)怎么诵叁?

例如,你可以將 DispatcherServlet 的 url-pattern 映射到 /app/钦椭,而不是 /拧额。你可以將 Theymeleaf 視圖放在 /WEB-INF/template/ 文件夾下,而不是 /WEB-INF/views 中彪腔。

所以基本上你希望 Spring 能自動(dòng)執(zhí)行這些操作侥锦,Spring 它有沒有提供一個(gè)簡(jiǎn)單靈活的方式來覆蓋掉默認(rèn)配置呢?

很好德挣,你即將踏進(jìn)入 Spring Boot 的世界恭垦,你將夢(mèng)想成真!

快速嘗試 Spring Boot

歡迎來到 Spring Boot 世界格嗅!Spring Boot 正是你一直在尋找的番挺。它可以自動(dòng)為你完成某些事情,但如果有必要屯掖,你可以覆蓋掉這些默認(rèn)配置玄柏。

與其夸夸而談,不如來點(diǎn)案例實(shí)戰(zhàn)贴铜。

步驟 1粪摘、創(chuàng)建一個(gè)基于 Maven 的 Spring Boot 應(yīng)用

創(chuàng)建一個(gè) Maven 項(xiàng)目并配置如下依賴:

<?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、為實(shí)體創(chuàng)建一個(gè) JPA 實(shí)體和 Spring Data JPA 資源庫(kù)接口

springmvc-jpa-demo 應(yīng)用一樣映砖,創(chuàng)建 User.java间坐、UserRepository.javaHomeController.java

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

springmvc-jpa-demo 項(xiàng)目中復(fù)制之前創(chuàng)建的 /WEB-INF/views/index.htmlsrc/main/resources/template 文件夾中竹宋。

步驟 5、創(chuàng)建 Spring Boot 入口類

創(chuàng)建一個(gè)含有 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)作一個(gè) Java 應(yīng)用運(yùn)行蜈七,并將你的瀏覽其指向 http://localhost:8080/

不出意外莫矗,你將看到一個(gè)以表格的形式展示的用戶列表飒硅,真的很酷!

我仿佛聽到你在喊:“這到底發(fā)生了什么事作谚?”三娩。

讓我解釋剛剛所發(fā)生的事情。

  1. 簡(jiǎn)單的依賴管理

    • 首先要注意的是我們使用了一些名為 spring-boot-start-* 的依賴妹懒。記住我說過我花費(fèi) 95% 的時(shí)間來配置同樣的配置雀监。當(dāng)你在開發(fā) Spring MVC 應(yīng)用時(shí)添加了 spring-boot-start-web 依賴,它已經(jīng)包含了一些常用的類庫(kù)眨唬,比如 spring-webmvc会前、jackson-jsonvalidation-apitomcat 等匾竿。

    • 我們添加了 spring-boot-starter-data-jpa 依賴瓦宜。它包含了所有的 spring-data-jpa 依賴,并且還添加了 Hibernate 庫(kù)搂橙,因?yàn)楹芏鄳?yīng)用使用 Hibernate 作為 JPA 實(shí)現(xiàn)歉提。

  2. 自動(dòng)配置

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

    • 我們還添加了 spring-boot-starter-Thymeleaf侄泽,它不僅添加了 Thymeleaf 的依賴,還自動(dòng)配置了 ThymeleafViewResolver bean蜻韭。

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

  3. 支持嵌入式 Servlet 容器

    • 最重要且最讓人驚訝的是娩怎,我們創(chuàng)建了一個(gè)簡(jiǎn)單的 Java 類搔课,標(biāo)記了一個(gè)神奇的注解 @SpringApplication,它有一個(gè) main 方法截亦。通過運(yùn)行 main 方法册踩,我們可以啟動(dòng)這個(gè)應(yīng)用稀颁,并可通過 http://localhost:8080/ 來訪問青灼。

Servlet 容器來自哪里帽借?

我們添加了 spring-boot-starter-web,它會(huì)自動(dòng)引入 spring-boot-starter-tomcat谷遂。當(dāng)我們運(yùn)行 main() 方法時(shí),它將 tomcat 作為一個(gè)嵌入式容器啟動(dòng)卖鲤,我們不需要部署自己的應(yīng)用到外部安裝好的 tomcat 上肾扰。

順便說一句,你看到我們?cè)?pom.xml 中配置的打包類型是 jar 而不是 war蛋逾,真有趣集晚!

非常好,但如果我想使用 jetty 服務(wù)器而不是 tomcat 呢区匣?很簡(jiǎn)單偷拔,只需要從 spring-boot-starter-web 中排除掉 sprig-boot-starter-tomcat,并包含 spring-boot-starter-jetty 依賴即可亏钩。

就是這樣莲绰。

但這看起來真的很神奇!

我可以想象此時(shí)你在想什么姑丑。你正在感嘆 Spring Boot 真的很酷蛤签,它為你自動(dòng)完成了很多事情。但是栅哀,你還沒了完全明白它幕后是怎樣工作的震肮,對(duì)不對(duì)称龙?

我可以理解,就像觀看魔術(shù)表演戳晌,過程非常有趣鲫尊,但你不知道魔術(shù)師是如何做到的。軟件開發(fā)則不一樣沦偎,你不用擔(dān)心马昨,未來我們還將看到各種新奇的東西,并在以后的文章中詳細(xì)地解釋它們幕后的工作原理扛施。很遺憾的是鸿捧,我不能在這篇文章中把所有的東西都教給你。

總結(jié)

在本文中疙渣,我們快速介紹了 Spring 的各種配置風(fēng)格匙奴,并了解了配置 Spring 應(yīng)用的復(fù)雜性。此外妄荔,我們通過創(chuàng)建一個(gè)簡(jiǎn)單的 Web 應(yīng)用來快速了解 Spring Boot泼菌。

在下一篇文章中,我們將深入了解 Spring Boot啦租,了解它的工作原理哗伯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市篷角,隨后出現(xiàn)的幾起案子焊刹,更是在濱河造成了極大的恐慌,老刑警劉巖恳蹲,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虐块,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡嘉蕾,警方通過查閱死者的電腦和手機(jī)贺奠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來错忱,“玉大人儡率,你說我怎么就攤上這事∫郧澹” “怎么了儿普?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)玖媚。 經(jīng)常有香客問我箕肃,道長(zhǎng),這世上最難降的妖魔是什么今魔? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任勺像,我火速辦了婚禮障贸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吟宦。我一直安慰自己篮洁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布殃姓。 她就那樣靜靜地躺著袁波,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蜗侈。 梳的紋絲不亂的頭發(fā)上篷牌,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音踏幻,去河邊找鬼枷颊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛该面,可吹牛的內(nèi)容都是我干的夭苗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼隔缀,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼题造!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起猾瘸,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤界赔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后须妻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仔蝌,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年荒吏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渊鞋。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绰更,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锡宋,到底是詐尸還是另有隱情儡湾,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布执俩,位于F島的核電站徐钠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏役首。R本人自食惡果不足惜尝丐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一显拜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爹袁,春花似錦远荠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至盹兢,卻和暖如春邻梆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绎秒。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工浦妄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人替裆。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓校辩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親辆童。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宜咒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

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