SpringBoot in Action——项目构建

SpringBoot结构

通常情况下,你创建的spring boot的结构如下:
SpringBoot in Action——项目构建_第1张图片

  • build.gradle:当然build.gradle也可以换为pom,xml。
  • Application.java:一个带有main()方法的类,用于引导启动应用程序。
  • ApplicationTest.java:一个空的JUnit测试类,它加载了一个使用Spring boot自动配置功能的Spring应用上下文。
  • application.properties:一个空的properties文件,你可以根据需要添加配置属性。
  • static目录:放置Web应用程序的静态内容(如javascript、样式表css、图片等等)。
  • templates目录:用于呈现模型数据的模版。

开发第一个应用程序

在本书,我们会构建一个简单的阅读列表应用程序。在这个程序里,用户可以输入想读的图书信息,查看列表,删除已经读过的书。我们将使用Spring boot来开发。
从技术角度来看,我们要使用Spring Mvc来处理Web请求,用Thymeleaf来定义Web视图,用Spring Data JPA来把阅读列表持久化到数据库里,姑且先用嵌入式的H2数据库。

启动引导Spring

package readinglist;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ReadingListApplication {
	public static void main(String[] args) {
		SpringApplication.run(ReadingListApplication.class, args);
	}
}

这里的@SpringBootApplication开启了组件扫描和自动配置功能,实际上,它糅合了三个有用的注解:

  • Spring的@Configuration:表示它是配置类。
  • Spring的@ComponentScan:开启组件扫描
  • Spring Boot的@EnableAutoConfiguration:开启自动配置,这个不起眼的注释也可以称为@Abracadabra,仔细念,就像魔咒一样,让你不用再写成篇的配置了。

配置应用程序属性
application.properties可以帮助你细粒度的调整Spring boot的自动配置,比如你可以添加一行:
server.port=8000
加上这样一行,你的嵌入式Tomcat的监听端口就变成了8000,而不是默认的8080.

Spring Boot依赖

覆盖起步依赖引入的传递依赖

以Spring Boot的Web起步依赖为例,它传递依赖了Jackson JSON库。如果你正在构建一个生产或消费JSON资源表述的REST服务,那它会很有用。但是,要构建传统的面向人类用户的Web应用程序,你可能用不上Jackson。虽然把它加进来也不会有什么坏处,但排除掉它的传递依赖,可以为你的项目瘦身
如果在用Gradle,你可以这样排除传递依赖:

compile("org.springframework.boot:spring-boot-starter-web") {
exclude group: 'com.fasterxml.jackson.core'
}

在Maven里,可以用元素来排除传递依赖。下面这个引入Spring Boot的build.gradle的增加了元素去除Jackson:

<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-starter-webartifactId>
		<exclusions>
			<exclusion>
				<groupId>com.fasterxml.jackson.coregroupId>
			exclusion>
		exclusions>
dependency>

另一方面,也许项目需要Jackson,但你需要用另一个版本的Jackson来进行构建,而不是Web起步依赖里的那个。假设Web起步依赖引用了Jackson 2.3.4,但你需要使用2.4.3。在Maven里,你可以直接在pom.xml中表达诉求,就像这样:

<dependency>
	<groupId>com.fasterxml.jackson.coregroupId>
	<artifactId>jackson-databindartifactId>
	<version>2.4.3version>
dependency>

Maven总是会用最近的依赖,也就是说,你在项目的构建说明文件里增加的这个依赖,会覆盖传递依赖引入的另一个依赖。与之类似,如果你用的是Gradle,可以在build.gradle文件里指明你要的Jackson的版本:
compile("com.fasterxml.jackson.core:jackson-databind:2.4.3")
因为这个依赖的版本比Spring Boot的Web起步依赖引入的要新,所以在Gradle里是生效的。

使用自动配置

Spring Boot的自动配置是一个运行时(更准确地说,是应用程序启动时)的过程,考虑了众多因素,才决定Spring配置应该用哪个,不该用哪个。

专注于应用程序功能

我们学习Spring和Spring mvc,往往需要在Configuration里面配置一堆template、factory、datasource。而且要使用一堆@Bean进行显示声明。
显然,如果我们不知道有Spring boot这种东西,我们还能忍受一堆和实际代码无关的配置,但是既然有这种自动配置,我们为什么还要忍耐呢?

但是在没有配置代码的情况下,很难描述自动配置。与其花时间讨论那些你不用做的事情,不如在这一节里关注一下你要做的事——写代码。
在向应用程序加入Spring Boot时,有个名为spring-boot-autoconfigure的JAR文件,其中包含了很多配置类。每个配置类都在应用程序的Classpath里,都有机会为应用程序的配置添砖加瓦。 这些配置类里有用于Thymeleaf的配置,有用于Spring Data JPA的配置,有用于Spiring MVC的配置,还有很多其他东西的配置,你可以自己选择是否在Spring应用程序里使用它们。

在Spring里可以很方便地编写你自己的条件,你所要做的就是实现Condition接口,覆盖它的matches()方法。

举例来说,下面这个简单的条件类只有在Classpath里存在JdbcTemplate时才会生效:

package readinglist;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class JdbcTemplateCondition implements Condition {
	@Override
	public boolean matches(ConditionContext context,
		AnnotatedTypeMetadata metadata) {
	try {
		context.getClassLoader().loadClass(
			"org.springframework.jdbc.core.JdbcTemplate");
		return true;
	} catch (Exception e) {
		return false;}
	}
}

当你用Java来声明Bean的时候,可以使用这个自定义条件类:

@Conditional(JdbcTemplateCondition.class)
public MyService myService() {
...
}

在这个例子里,只有当JdbcTemplateCondition类的条件成立时才会创建MyService这个Bean。也就是说MyService Bean创建的条件是Classpath里有JdbcTemplate。否则,这个Bean的声明就会被忽略掉。
SpringBoot in Action——项目构建_第2张图片

我们来看看Spring boot自动配置的源代码:

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {
...
}

如你所见,DataSourceAutoConfiguration添加了@Configuration注解,它从其他配置类里导入了一些额外配置,还自己定义了一些Bean。最重要的是,DataSourceAutoConfiguration上添加了@ConditionalOnClass注解,要求Classpath里必须要有DataSource和EmbeddedDatabaseType。如果它们不存在,条件就不成立,DataSourceAutoConfiguration提供的配置都会被忽略掉。

你可能感兴趣的:(SpringBoot in Action——项目构建)