使用Spring Boot很容易建立一个独立运行(运行jar,内嵌Servlet容器)、准生产级别的基于Spring框架的项目,使用Spring Boot你能够不用或者只须要不多的Spring配置。 html
Spring将不少魔法带入了Spring应用程序的开发之中,其中最重要的是如下四个核心。java
Java版本:推荐使用java8mysql
构建一个Sping Boot的Maven项目,强烈推荐Spring Initializr,它从本质上来讲就是一个Web应用程序,它能为你生成Spring Boot项目结构。
Spring Initializr有几种用法:git
@SpringBootApplication是Sprnig Boot项目的核心注解,主要目的是开启自动配置。
使用命令 mvn spring-boot:run”在命令行启动该应用github
spring-boot配置文件application.properties支持的属性列表:http://docs.spring.io/spring-...
一、直接在要使用的地方经过注解@Value(value=”${configName}”)就能够绑定到你想要的属性上面。
二、在application.properties中的各个参数之间也能够直接引用来使用。web
com.name="111" com.want="222" com.dudu.yearhope=${com.name}-${com.want}
三、有时候属性太多了,一个个绑定到属性字段上太累,官方提倡绑定一个对象的bean,这里咱们建一个ConfigBean.java类,顶部须要使用注解@ConfigurationProperties(prefix = “com.xxx”)来指明使用哪一个.这点能够参考:org.springframework.boot.autoconfigure.jdbc.DataSourceProperties类的写法spring
这里配置完还须要在spring Boot入口类加上@EnableConfigurationProperties并指明要加载哪一个bean
好比:@EnableConfigurationProperties(DataSourceProperties.class)sql
四、有时候咱们不但愿把全部配置都放在application.properties里面,这时候咱们能够另外定义一个,如test.properties,路径跟也放在src/main/resources下面。
咱们新建一个bean类,以下:shell
@Configuration @ConfigurationProperties(prefix = "com.md") @PropertySource("classpath:test.properties") public class ConfigTestBean { private String name; private String want; // 省略getter和setter }
五、随机值配置
配置文件中${random} 能够用来生成各类不一样类型的随机值,从而简化了代码生成的麻烦,例如 生成 int 值、long 值或者 string 字符串。数据库
dudu.number=${random.int} dudu.uuid=${random.uuid} dudu.number.less.than.ten=${random.int(10)} dudu.number.in.range=${random.int[1024,65536]}
六、外部配置-命令行参数配置
如java -jar xx.jar --server.port=9090
其中server.port是application.properties里面的选项
七、Profile-多环境配置
在Spring Boot中多环境配置文件名须要知足application-{profile}.properties的格式,其中{profile}对应你的环境标识,好比:
application-dev.properties:开发环境
application-prod.properties:生产环境
想要使用对应的环境,有两种方式
spring.profiles.active
属性来设置,值对应上面提到的{profile},这里就是指dev、prod这2个。java -jar xxx.jar --spring.profiles.active=dev
$ export SPRING_PROFILES_ACTIVE=production
在代码里,咱们还能够直接用@Profile
注解来进行配置
以下:
/** * 测试数据库 */ @Component @Profile("testdb") public class TestDBConnector implements DBConnector { @Override public void configure() { System.out.println("testdb"); } } /** * 生产数据库 */ @Component @Profile("devdb") public class DevDBConnector implements DBConnector { @Override public void configure() { System.out.println("devdb"); } }
经过在配置文件激活具体使用哪一个实现类spring.profiles.active=testdb
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
@SpringBootApplication背后:打开源码看看,有三个Annotation原注解:
@EnableAutoConfiguration这个Annotation最为重要(点开源码看看),Spring框架提供的各类名字为@Enable开头的Annotation定义?好比@EnableScheduling、@EnableCaching、@EnableMBeanExport等,@EnableAutoConfiguration的理念和作事方式其实一脉相承,简单归纳一下就是,借助@Import的支持,收集和注册特定场景相关的bean定义。
借助于Spring框架原有的一个工具类:SpringFactoriesLoader的支持,@EnableAutoConfiguration能够智能的自动配置 SpringFactoriesLoader
属于Spring框架私有的一种扩展方案,其主要功能就是从指定的配置文件META-INF/spring.factories
加载配置。
@EnableAutoConfiguration自动配置的魔法骑士是从classpath中搜寻全部的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项(主要在SpringBoot的autoconfigure依赖包中)经过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,而后汇总为一个并加载到IoC容器。
1) 若是使用的是SpringApplication.run静态方法,那么,这个方法里面首先要建立一个SpringApplication实例,在初始化的时候,它会提早作几件事情:
ApplicationContextInitializer,ApplicationListener
2)执行run方法的逻辑,首先遍历执行全部经过SpringFactoriesLoader能够查找到并加载的SpringApplicationRunListener。调用它们的started()方法。而后
建立并配置当前Spring Boot应用将要使用的Environment(包括配置要使用的PropertySource以及Profile)。而后遍历调用全部SpringApplicationRunListener的environmentPrepared()的方法。以后,若是SpringApplication的showBanner属性被设置为true,则打印banner。
3) 根据用户是否明确设置了applicationContextClass类型以及初始化阶段的推断结果,决定该为当前SpringBoot应用建立什么类型的ApplicationContext并建立完成,而后根据条件决定是否添加ShutdownHook,决定是否使用自定义的BeanNameGenerator,决定是否使用自定义的ResourceLoader,固然,最重要的,将以前准备好的Environment设置给建立好的ApplicationContext使用。
4) ApplicationContext建立好以后,遍历调用先前找到的ApplicationContextInitializer的initialize(applicationContext)方法来对已经建立好的ApplicationContext进行进一步的处理。
5) 遍历调用全部SpringApplicationRunListener的contextPrepared()方法。
6) 最核心的一步,将以前经过@EnableAutoConfiguration获取的全部配置以及其余形式的IoC容器配置加载到已经准备完毕的ApplicationContext。
7) 遍历调用全部SpringApplicationRunListener的contextLoaded()方法。
8) 调用ApplicationContext的refresh()方法,完成IoC容器可用的最后一道工序。
9) 查找当前ApplicationContext中是否注册有CommandLineRunner,若是有,则遍历执行它们。
10) 正常状况下,遍历执行SpringApplicationRunListener的finished()方法.
Spring Boot为Spring MVC提供适用于多数应用的自动配置功能。在Spring默认基础上,自动配置添加了如下特性:
若是想全面控制Spring MVC,你能够添加本身的@Configuration,并使用@EnableWebMvc对其注解。若是想保留Spring Boot MVC的特性,并只是添加其余的MVC配置(拦截器,formatters,视图控制器等),你能够添加本身的WebMvcConfigurerAdapter
类型的@Bean(不使用@EnableWebMvc注解)
例如:配置一个拦截器
@Configuration public class WebConfiguration extends WebMvcConfigurerAdapter { @Bean public RemoteIpFilter remoteIpFilter() { return new RemoteIpFilter(); } @Bean public LocaleChangeInterceptor localeChangeInterceptor() { return new LocaleChangeInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry { registry.addInterceptor(localeChangeInterceptor()); } }
Spring Boot 默认为咱们提供了静态资源处理,使用 WebMvcAutoConfiguration 中的配置各类属性。
建议你们使用Spring Boot的默认配置方式,提供的静态资源映射以下:
这使用了Spring MVC的ResourceHttpRequestHandler.
Spring Boot支持多种模版引擎包括:
JSP技术Spring Boot官方是不推荐的,缘由有三:
当你使用上述模板引擎中的任何一个,它们默认的模板配置路径为:src/main/resources/templates。固然也能够修改这个路径
Spring Boot自动配置的默认错误处理器会查找名为error
的视图,若是找不到就用默认的白标
错误视图,如图3-1所示。所以,最简单的方法就是建立一个自定义视图,让解析出的视图名为
error。
这一点归根到底取决于错误视图解析时的视图解析器。
Spring Boot会为错误视图提供以下错误属性。
spring-boot-starter-logging
根据不一样的日志系统,你能够按以下规则组织配置文件名,就能被正确加载:
若是你不想用logback.xml做为Logback配置的名字,能够经过logging.config属性指定自定义的名字:
logging.config=classpath:logging-config.xml
据不一样环境(prod:生产环境,test:测试环境,dev:开发环境)来定义不一样的日志输出,在 logback-spring.xml中使用 springProfile 节点来定义,方法以下:文件名称不是logback.xml,想使用spring扩展profile支持,要以logback-spring.xml命名
<!-- 测试环境+开发环境. 多个使用逗号隔开. --> <springProfile name="test,dev"> <logger name="com.dudu.controller" level="info" /> </springProfile> <!-- 生产环境. --> <springProfile name="prod"> <logger name="com.dudu.controller" level="ERROR" /> </springProfile>
能够启动服务的时候指定 profile (如不指定使用默认),如指定prod 的方式为:
java -jar xxx.jar –spring.profiles.active=prod
一、使用普通jdbc
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
application.properties中配置数据源信息。
spring.datasource.url = jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8 spring.datasource.username = root spring.datasource.password = root spring.datasource.driver-class-name = com.mysql.jdbc.Driver
自定义数据源
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.19</version> </dependency>
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Autowired private Environment env; //destroy-method="close"的做用是当数据库链接不使用的时候,就把该链接从新放到数据池中,方便下次使用调用. @Bean(destroyMethod = "close") public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl(env.getProperty("spring.datasource.url")); dataSource.setUsername(env.getProperty("spring.datasource.username"));//用户名 dataSource.setPassword(env.getProperty("spring.datasource.password"));//密码 dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name")); dataSource.setInitialSize(2);//初始化时创建物理链接的个数 dataSource.setMaxActive(20);//最大链接池数量 dataSource.setMinIdle(0);//最小链接池数量 dataSource.setMaxWait(60000);//获取链接时最大等待时间,单位毫秒。 dataSource.setValidationQuery("SELECT 1");//用来检测链接是否有效的sql dataSource.setTestOnBorrow(false);//申请链接时执行validationQuery检测链接是否有效 dataSource.setTestWhileIdle(true);//建议配置为true,不影响性能,而且保证安全性。 dataSource.setPoolPreparedStatements(false);//是否缓存preparedStatement,也就是PSCache return dataSource; } }
Spring Boot自动配置自带了不少配置类,每个都能运用
在你的应用程序里。它们都使用了Spring 4.0的条件化配置,能够在运行时判断这个配置是该被运
用,仍是该被忽略。如:
@Bean @ConditionalOnMissingBean(JdbcOperations.class) public JdbcTemplate jdbcTemplate() { return new JdbcTemplate(this.dataSource); }
条件注解有以下:
@RunWith(SpringRunner.class) @SpringBootTest(classes = App.class) public MyTest{ @Test public void test1(){ } }
一、普通测试
@RunWith(SpringRunner.class) @SpringBootTest(classes = App.class) @WebAppConfiguration public class MockMvcWebTests { @Autowired private WebApplicationContext webContext; private MockMvc mockMvc; @Before public void setupMockMvc() { mockMvc = MockMvcBuilders.webAppContextSetup(webContext).build(); } @Test public void homePage() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/readingList")) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.view().name("readingList")) .andExpect(MockMvcResultMatchers.model().attributeExists("books")) .andExpect(MockMvcResultMatchers.model().attribute("books", Matchers.is(Matchers.empty()))); } }
首先向/readingList发起一个GET请求,接下来但愿该
请求处理成功(isOk()会判断HTTP 200响应码),而且视图的逻辑名称为readingList。测试
还要判定模型包含一个名为books的属性,该属性是一个空集合。全部的断言都很直观。
二、测试运行中的应用程序 在测试类上添加, 以Spring的@Web-IntegrationTest
注解,能够声明你不只但愿Spring Boot为测试建立应用程序上下文,还要启动一个嵌入式的Servlet容器。一旦应用程序运行在嵌入式容器里,你就能够发起真实的HTTP请求,断言结果了。
这里采用@WebIntegration-Test,在服务器里启动了应用程序RestTemplate
对应用程序发起HTTP请求。
Spring-boot 1.4之后推荐采用SpringBootTest(webEnvironment=WebEnvironment.DEFINED_PORT) (or RANDOM_PORT)来代替@WebIntegrationTest,而此类在1.5已经被移除了。https://github.com/spring-pro...
@RunWith(SpringRunner.class) @SpringBootTest(classes = App.class,webEnvironment=WebEnvironment.RANDOM_PORT) public class WebInRuntimeTest { @Value("${local.server.port}") private int port; @Autowired private TestRestTemplate template; @Test public void test1(){ // Assert.state(true,"测试成功"); System.out.println(port); ResponseEntity<String> response=template.getForEntity("/test/111", String.class); System.out.println(response.getStatusCodeValue()); System.out.println(response.getHeaders()); System.out.println(response.getBody()); Assert.hasText("111","true"); } }
用随机端口启动服务器,@WebIntegrationTest的value属性接受一个String数组,数组中的每项都是键值对,形如name=value,用来设置测试中使用的属性。要设置server.port,你能够这样作:**@WebIntegrationTest("server.port:0") //使用0表示端口号随机,也能够具体指定如8888这样的固定端口.
或者直接这样@WebIntegrationTest(randomPort=true)**
Spring Boot将local.server.port的值设置为了选中的端口。咱们只需使用Spring的@Value注解将其注入便可:
@Value("${local.server.port}") private int port;
三、使用Selenium 测试HTML 页面
@RunWith(SpringRunner.class) @SpringBootTest(classes = App.class) @WebIntegrationTest(randomPort=true) public class ServerWebTests { private static FirefoxDriver browser; @Value("${local.server.port}") private int port; @BeforeClass public static void openBrowser() { browser = new FirefoxDriver(); browser.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); } @Test public void addBookToEmptyList() { String baseUrl = "http://localhost:" + port; browser.get(baseUrl); assertEquals("You have no books in your book list",browser.findElementByTagName("div").getText()); browser.findElementByName("title").sendKeys("BOOK TITLE"); browser.findElementByTagName("form").submit(); WebElement dl = browser.findElementByCssSelector("dt.bookHeadline"); assertEquals("BOOK TITLE by BOOK AUTHOR (ISBN: 1234567890)",dl.getText()); } @AfterClass public static void closeBrowser() { browser.quit(); } }
当咱们不想使用内嵌tomcat部署时,咱们也可使用外部tomcat,并打包成war:
https://docs.spring.io/spring...
一、Spring Loaded 实现热部署
Spring Loaded是一个用于在JVM运行时从新加载类文件更改的JVM代理,Spring Loaded容许你动态的新增/修改/删除某个方法/字段/构造方法,一样能够修改做用在类/方法/字段/构造方法上的注解.也能够新增/删除/改变枚举中的值。
spring-loaded是一个开源项目,项目地址:https://github.com/spring-pro...
Spring Loaded有两种方式实现,分别是Maven引入依赖方式或者添加启动参数方式
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.6.RELEASE</version> </dependency> </dependencies> </plugin>
启动:mvn spring-boot:run
注意:maven依赖的方式只适合spring-boot:run的启动方式,右键那种方式不行。
出现以下配置表实配置成功:
[INFO] Attaching agents: [C:Userstengj.m2repositoryorgspringframeworkspringloaded1.2.6.R
添加启动参数方式
这种方式是右键运行启动类.首先先下载对应的springloaded-xxx.RELEASE.jar,能够去上面提到的官网获取,在VM options中输入-javaagent:< pathTo >/springloaded-{VERSION}.jar
上面2种方式随便选择一种便可,当系统经过 mvn spring-boot:run启动或者 右键application debug启动Java文件时,系统会监视classes文件,当有classes文件被改动时,系统会从新加载类文件,不用重启启动服务。
注:IDEA下须要从新编译文件 Ctrl+Shift+F9或者编译项目 Ctrl+F9
在 Spring Boot,模板引擎的页面默认是开启缓存,若是修改页面内容,刷新页面是没法获取修改后的页面内容,因此,若是咱们不须要模板引擎的缓存,能够进行关闭。
spring.freemarker.cache=false spring.thymeleaf.cache=false spring.velocity.cache=false spring.mustache.cache=false
不过仍是有一些状况下须要从新启动,不可用的状况以下:
二、spring-boot-devtools 实现热部署
spring-boot-devtools为应用提供一些开发时特性,包括默认值设置,自动重启,livereload等。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies>
将依赖关系标记为可选< optional >true< /optional>是一种最佳作法,能够防止使用项目将devtools传递性地应用于其余模块。
在Spring Boot集成Thymeleaf时,spring.thymeleaf.cache属性设置为false能够禁用模板引擎编译的缓存结果。
如今,devtools会自动帮你作到这些,禁用全部模板的缓存,包括Thymeleaf, Freemarker, Groovy Templates, Velocity, Mustache等。
自动重启的原理在于spring boot使用两个classloader:不改变的类(如第三方jar)由base类加载器加载,正在开发的类由restart类加载器加载。应用重启时,restart类加载器被扔掉重建,而base类加载器不变,这种方法意味着应用程序从新启动一般比“冷启动”快得多,由于base类加载器已经可用并已填充。
因此,当咱们开启devtools后,classpath中的文件变化会致使应用自动重启。
固然不一样的IDE效果不同,Eclipse中保存文件便可引发classpath更新(注:须要打开自动编译),从而触发重启。而IDEA则须要本身手动CTRL+F9从新编译一下(感受IDEA这种更好,否则每修改一个地方就重启,好蛋疼)
排除静态资源文件
静态资源文件在改变以后有时候不必触发应用程序重启,例如thymeleaf模板文件就能够实时编辑,默认状况下,更改/META-INF/maven, /META-INF/resources ,/resources ,/static ,/public 或/templates下的资源不会触发重启,而是触发live reload(devtools内嵌了一个LiveReload server,当资源发生改变时,浏览器刷新,须要浏览器插件支持)。
可使用spring.devtools.restart.exclude属性配置,例如
spring.devtools.restart.exclude=static/**,public/**
若是想保留默认配置,同时增长新的配置,则可以使用
spring.devtools.restart.additional-exclude属性
观察额外的路径
若是你想观察不在classpath中的路径的文件变化并触发重启,则能够配置 spring.devtools.restart.additional-paths 属性。
不在classpath内的path能够配置spring.devtools.restart.additionalpaths属性来增长到监视中,同时配置spring.devtools.restart.exclude能够选择这些path的变化是致使restart仍是live reload。
关闭自动重启
设置 spring.devtools.restart.enabled 属性为false,能够关闭该特性。能够在application.properties中设置,也能够经过设置环境变量的方式。
public static void main(String[] args) { System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(MyApp.class, args); }
使用一个触发文件
若不想每次修改都触发自动重启,能够设置spring.devtools.restart.trigger-file指向某个文件,只有更改这个文件时才触发自动重启。
自定义自动重启类加载器
默认时,IDE中打开的项目都会由restart加载器加载,jar文件由Base加载器加载,可是若你使用multi-module的项目,而且不是全部模块都被导入到IDE中,此时会致使加载器不一致。这时你能够建立META-INF/spring-devtools.properties文件,并增长restart.exclude.XXX,restart.include.XXX来配置哪些jar被restart加载,哪些被base加载。如:
restart.include.companycommonlibs=/mycorp-common-[\\w-]+\.jar restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
若是您不想在应用程序运行时启动LiveReload服务器,则能够将spring.devtools.livereload.enabled属性设置为false。
一次只能运行一个LiveReload服务器。开始应用程序以前,请确保没有其余LiveReload服务器正在运行。
若是你的IDE启动多个应用程序,则只有第一个应用程序将支持LiveReload。
三、JRebel插件方式 :略
Spring Boot为两款流行的数据库迁移库提供了自动配置支持。
Flyway(http://flywaydb.org)
Liquibase(http://www.liquibase.org)
<dependency> <groupId>org.flywayfb</groupId> <artifactId>flyway-core</artifactId> </dependency>
Flyway是一个很是简单的开源数据库迁移库,使用SQL来定义迁移脚本。它的理念是,每一个
脚本都有一个版本号,Flyway会顺序执行这些脚本,让数据库达到指望的状态。它也会记录已执
行的脚本状态,不会重复执行。
,Flyway脚本就是SQL。让其发挥做用的是其在Classpath里的位置和文件名。Flyway
脚本都遵循一个命名规范,V版本号__描述.sql,如V1__initdb.sql
Flyway脚本须要放在src/main/resources/db/migration里。
你还须要将spring.jpa.hibernate.ddl-auto设置为none,由此告知Hibernate不要建立
数据表。
原理:在应用程序部署并运行起来后,Spring Boot会检测到Classpath里的Flyway,自动配置所需的
Bean。Flyway会依次查看/db/migration里的脚本,若是没有执行过就运行这些脚本。每一个脚本都
执行事后,向schema_version表里写一条记录。应用程序下次启动时,Flyway会先看schema_version
里的记录,跳过那些脚本。
相比Flyway的优势,数据库无关性,脚本不是用sql写,而是支持yaml,json,xml等格式。
<dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> </dependency>
具体介绍:略。
运行中的应用程序就像礼物盒。你能够刺探它,做出合理的推测,猜想它的运行状况。但如
何了解真实的状况呢?有没有一种办法能让你深刻应用程序内部一窥究竟,了解它的行为,检查
它的健康情况,甚至触发一些操做来影响应用程序呢?
Spring Boot的Actuator。它提供了不少生产级的特性,好比监控和度
量Spring Boot应用程序。Actuator的这些特性能够经过众多REST端点、远程shell和JMX得到。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
一、Actuator的Web端点
端点能够分为三大类:配置端点、度量端点和其余端点
/beans端点产生的报告能告诉你Spring应用程序上下文里都有哪些Bean。
/autoconfig端点能告
诉你为何会有这个Bean,或者为何没有这个Bean。
Spring Boot自动配置构建于Spring的条件化配置之上。它提供了众多带有
@Conditional注解的配置类,根据条件决定是否要自动配置这些Bean。/autoconfig端点提供了
一个报告,列出了计算过的全部条件,根据条件是否经过进行分组。
/env端点会生成应用程序可用的全部环境属性的列表,不管这些属性是否用到。这其中包括
环境变量、JVM属性、命令行参数,以及applicaition.properties或application.yml文件提供的属性。
/metrics端点提供了一些针对Web请求的基本计数器和计时器,但那些度量值缺乏详细信
息。知道所处理请求的更多信息是颇有帮助的,尤为是在调试时,因此就有了/trace这个端点。
/trace端点能报告全部Web请求的详细信息,包括请求方法、路径、时间戳以及请求和响应的
头信息
二、使用:CRaSH shell
三、经过JMX 监控应用程序
Book: Spring-Boot In Action
嘟嘟独立博客
https://github.com/tengj/Spri...