spring boot学习笔记(一)

来源:互联网 发布:淘宝客服中心代码 编辑:程序博客网 时间:2024/05/20 19:16

Spring Boot将很多魔法带入了Spring应用程序的开发之中,其中最重要的是以下四个核心。

1.自动配置:针对很多Spring应用程序常见的应用功能,Spring Boot能自动提供相关配置。

2.起步依赖:告诉Spring Boot需要什么功能,它就能引入需要的库。

3.命令行界面:这是Spring Boot的可选特性,借此你只需写代码就能完成完整的应用程序,无需传统项目构建。

4.Actuator:让你能够深入运行中的Spring Boot应用程序,一探究竟。


1.什么是spring boot自动配置

Spring Boot的自动配置给开发者带来了很大的便利,当开发人员在pom文件中或是build文件中添加starter依赖后,maven或者gradle会自动下载很多jar包到classpath中。当Spring Boot检测到特定类的存在,就会针对这个应用做一定的配置,自动创建和织入需要的spring bean到程序上下文中。Spring Boot使用了Spring 4.0的条件化配置,可以在运行时判断这个配置是该被运用,还是该被忽略。Spring Boot自动配置自带了很多配置类,每一个都能运用在你的应用程序里。

简而言之,Spring Boot的自动配置是一个运行时(更准确地说,是应用程序启动时)的过程。

举个例子,项目中使用jdbcTemplate,Spring的JdbcTemplate是不是在Classpath里?如果是,并且有DataSource的Bean,则自动配置一个JdbcTemplate的Bean。每当应用程序启动的时候,Spring Boot的自动配置都要做将近200个这样的决定,涵盖安全、集成、持久化、Web开发等诸多方面。所有这些自动配置就是为了尽量不让你自己写配置。

springboot 程序入口,示例:

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

在Spring Boot项目中,xxxApplication.java会作为应用程序的入口,是一个启动引导类,负责程序启动以及一些基础性的工作。@SpringBootApplication是这个注解是该应用程序入口的标志,然后有熟悉的main函数,通过SpringApplication.run(xxxApplication.class, args)来运行Spring Boot应用。打开SpringBootApplication注解可以发现,它是由其他几个类组合而成的:
@Configuration(标明该类使用Spring基于Java的配置,使用Java文件做配置可以检查类型安全)、
@EnableAutoConfiguration(就是这一行配置开启了Spring Boot自动配置的魔力,让你不用再写成篇的配置了)、
@ComponentScan(启用组件扫描,这样你写的Web控制器类和其他组件才能被自动发现并注册为Spring应用程序上下文里的Bean)。


spring自动配置其实是spring帮助我们完成了,那这个配置总得有人写,这块代买在哪里呢?

在向应用程序加入Spring Boot时,有个名为spring-boot-autoconfigure的JAR文件,其中包含了很多配置类。每个配置类都在应用程序的Classpath里,都有机会为应用程序的配置添砖加瓦。这些配置类里有用于Thymeleaf的配置,有用于Spring Data JPA的配置,有用于Spiring MVC的配置,还有很多其他东西的配置,你可以自己选择是否在Spring应用程序里使用它们。所有这些配置如此与众不同,原因在于它们利用了Spring的条件化配置,这是Spring 4.0引入的新特性。条件化配置允许配置存在于应用程序中,但在满足某些特定条件之前都忽略这个配置。

举例来说,下面这个简单的条件类只有在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 {@Overridepublic 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的声明就会被忽略掉。
附上自动配置中使用的条件化注解
条件化注解                                                                        配置生效条件
@ConditionalOnBean                                                 配置了某个特定Bean
@ConditionalOnMissingBean                                     没有配置特定的Bean
@ConditionalOnClass                                                 Classpath里有指定的类
@ConditionalOnMissingClass                                     Classpath里缺少指定的类
@ConditionalOnExpression                                        给定的Spring Expression Language(SpEL)表达式计算结果为true
@ConditionalOnJava                                                  Java的版本匹配特定值或者一个范围值
@ConditionalOnJndi                                                   参数中给定的JNDI位置必须存在一个,如果没有给参数,则要有JNDIInitialContext
@ConditionalOnProperty                                            指定的配置属性要有一个明确的值
@ConditionalOnResource                                          Classpath里有指定的资源
@ConditionalOnWebApplication                                 这是一个Web应用程序

@ConditionalOnNotWebApplication                           这不是一个Web应用程序

2.什么是spring boot起步依赖

起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。很多起步依赖的命名都暗示了它们提供的某种或某类功能

例如我们想要要构建一个Web应用程,在build文件中加入
dependencies {
    compile "org.springframework.boot:spring-boot-starter-web"
}
通过传递依赖,添加这个依赖就等价于加了支持web功能的独立的库。我们并没有说想要Spring MVC,
只是说想要构建一个Web应用程序

起步依赖的版本问题

我们并不需要指定版本号,起步依赖本身的版本是由正在使用的Spring Boot的版本来决定的,而起步依赖则会决定它们引入的传递依赖的版本。不知道自己所用依赖的版本,你多少会有些不安。你要有信心,相信Spring Boot经过了足够的测试,确保引入的全部依赖都能相互兼容。这是一种解脱,只需指定起步依赖,不用担心自己需要维护哪些库,也不必担心它们的版本。但如果你真想知道自己在用什么,在构建工具里总能找到你要的答案。

在Gradle里,dependencies任务会显示一个依赖树,其中包含了项目所用的每一个库以及它们的版本:

$ gradle dependencies
在Maven里使用dependency插件的tree目标也能获得相似的依赖树。
$ mvn dependency:tree

排除传递依赖中的库

以Spring Boot的Web起步依赖为例,它传递依赖了Jackson JSON库,如果我们不想要这个库,怎么办呢
如果在用Gradle,你可以这样排除传递依赖:
compile("org.springframework.boot:spring-boot-starter-web") {
exclude group: 'com.fasterxml.jackson.core'
}
在Maven里,可以用<exclusions>元素来排除传递依赖。下面这个引入Spring Boot的
build.gradle的<dependency>增加了<exclusions>元素去除Jackson:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>

</dependency>

改变传递依赖库的版本

如果你用的是Gradle,可以在build.gradle文件里指明你要的Jackson的版本:
compile("com.fasterxml.jackson.core:jackson-databind:2.4.3")

因为这个依赖的版本比Spring Boot的Web起步依赖引入的要新,所以在Gradle里是生效的。但假如你要的不是新版本的Jackson,而是一个较早的版本呢?Gradle和Maven不太一样,Gradle倾向于使用库的最新版本。因此,如果你要使用老版本的Jackon,则不得不把老版本的依赖加入构建,并把Web起步依赖传递依赖的那个版本排除掉:

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

在Maven里,你可以直接在pom.xml中表达诉求,就像这样:

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>

Maven总是会用最近的依赖,也就是说,你在项目的构建说明文件里增加的这个依赖,会覆盖传递依赖引入的另一个依赖。


原创粉丝点击