原文: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 的 EntityManagerFactory 和 JpaTransactionManager 定義 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 中下載并配置像 Tomcat、Jetty 或者 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窗怒、EntityManagerFactory 和 TransactionManager 等 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.java 和 HomeController.java。
步驟 4邑退、創(chuàng)建用于顯示用戶列表的 Thymeleaf 視圖
從 springmvc-jpa-demo
項(xiàng)目中復(fù)制之前創(chuàng)建的 /WEB-INF/views/index.html
到 src/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ā)生的事情。
-
簡(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-json、validation-api 和 tomcat 等匾竿。我們添加了
spring-boot-starter-data-jpa
依賴瓦宜。它包含了所有的spring-data-jpa
依賴,并且還添加了 Hibernate 庫(kù)搂橙,因?yàn)楹芏鄳?yīng)用使用 Hibernate 作為 JPA 實(shí)現(xiàn)歉提。
-
自動(dòng)配置
spring-boot-starter-web
不僅添加了上面所說的這些庫(kù),還配置了經(jīng)常被注冊(cè)的 bean区转,比如 DispatcherServlet苔巨、ResourceHandler 和 MessageSource 等 bean,并且應(yīng)用了合適的默認(rèn)配置废离。我們還添加了
spring-boot-starter-Thymeleaf
侄泽,它不僅添加了 Thymeleaf 的依賴,還自動(dòng)配置了 ThymeleafViewResolver bean蜻韭。雖然我們沒有定義任何 DataSource悼尾、EntityManagerFactory 和 TransactionManager 等 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è) EntityManagerFactory 和 TransactionManager 等 bean司草。但是我們使用的是 MySQL,因此我們需要明確提供 MySQL 的連接信息泡仗。我們已經(jīng)在
application.properties
文件中配置了 MySQL 連接信息埋虹,Spring Boot 將應(yīng)用這些配置來創(chuàng)建 DataSource。
-
支持嵌入式 Servlet 容器
- 最重要且最讓人驚訝的是娩怎,我們創(chuàng)建了一個(gè)簡(jiǎn)單的 Java 類搔课,標(biāo)記了一個(gè)神奇的注解
@SpringApplication
,它有一個(gè)main
方法截亦。通過運(yùn)行main
方法册踩,我們可以啟動(dòng)這個(gè)應(yīng)用稀颁,并可通過http://localhost:8080/
來訪問青灼。
- 最重要且最讓人驚訝的是娩怎,我們創(chuàng)建了一個(gè)簡(jiǎn)單的 Java 類搔课,標(biāo)記了一個(gè)神奇的注解
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啦租,了解它的工作原理哗伯。